xref: /aosp_15_r20/external/clang/test/CodeGen/builtins-multiprecision.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple "i686-unknown-unknown"   -emit-llvm -x c %s -o - -O3 | FileCheck %s
2*67e74705SXin Li // RUN: %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - -O3 | FileCheck %s
3*67e74705SXin Li // RUN: %clang_cc1 -triple "x86_64-mingw32"         -emit-llvm -x c %s -o - -O3 | FileCheck %s
4*67e74705SXin Li 
test_addcb(unsigned char x,unsigned char y,unsigned char carryin,unsigned char * z)5*67e74705SXin Li unsigned char test_addcb(unsigned char x, unsigned char y,
6*67e74705SXin Li                          unsigned char carryin, unsigned char *z) {
7*67e74705SXin Li   // CHECK: @test_addcb
8*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %x, i8 %y)
9*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 1
10*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 0
11*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %{{.+}}, i8 %carryin)
12*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 1
13*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 0
14*67e74705SXin Li   // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
15*67e74705SXin Li   // CHECK: %{{.+}} = zext i1 %{{.+}} to i8
16*67e74705SXin Li   // CHECK: store i8 %{{.+}}, i8* %z, align 1
17*67e74705SXin Li 
18*67e74705SXin Li   unsigned char carryout;
19*67e74705SXin Li   *z = __builtin_addcb(x, y, carryin, &carryout);
20*67e74705SXin Li 
21*67e74705SXin Li   return carryout;
22*67e74705SXin Li }
23*67e74705SXin Li 
test_addcs(unsigned short x,unsigned short y,unsigned short carryin,unsigned short * z)24*67e74705SXin Li unsigned short test_addcs(unsigned short x, unsigned short y,
25*67e74705SXin Li                           unsigned short carryin, unsigned short *z) {
26*67e74705SXin Li   // CHECK: @test_addcs
27*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 %x, i16 %y)
28*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 1
29*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 0
30*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 %{{.+}}, i16 %carryin)
31*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 1
32*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 0
33*67e74705SXin Li   // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
34*67e74705SXin Li   // CHECK: %{{.+}} = zext i1 %{{.+}} to i16
35*67e74705SXin Li   // CHECK: store i16 %{{.+}}, i16* %z, align 2
36*67e74705SXin Li 
37*67e74705SXin Li   unsigned short carryout;
38*67e74705SXin Li   *z = __builtin_addcs(x, y, carryin, &carryout);
39*67e74705SXin Li 
40*67e74705SXin Li   return carryout;
41*67e74705SXin Li }
42*67e74705SXin Li 
test_addc(unsigned x,unsigned y,unsigned carryin,unsigned * z)43*67e74705SXin Li unsigned test_addc(unsigned x, unsigned y, unsigned carryin, unsigned *z) {
44*67e74705SXin Li   // CHECK: @test_addc
45*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
46*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 1
47*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 0
48*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %carryin)
49*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 1
50*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 0
51*67e74705SXin Li   // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
52*67e74705SXin Li   // CHECK: %{{.+}} = zext i1 %{{.+}} to i32
53*67e74705SXin Li   // CHECK: store i32 %{{.+}}, i32* %z, align 4
54*67e74705SXin Li   unsigned carryout;
55*67e74705SXin Li   *z = __builtin_addc(x, y, carryin, &carryout);
56*67e74705SXin Li 
57*67e74705SXin Li   return carryout;
58*67e74705SXin Li }
59*67e74705SXin Li 
test_addcl(unsigned long x,unsigned long y,unsigned long carryin,unsigned long * z)60*67e74705SXin Li unsigned long test_addcl(unsigned long x, unsigned long y,
61*67e74705SXin Li                          unsigned long carryin, unsigned long *z) {
62*67e74705SXin Li   // long is i32 on i686, i64 on x86_64.
63*67e74705SXin Li   // CHECK: @test_addcl([[UL:i32|i64]] %x
64*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { [[UL]], i1 } @llvm.uadd.with.overflow.[[UL]]([[UL]] %x, [[UL]] %y)
65*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 1
66*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 0
67*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { [[UL]], i1 } @llvm.uadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %carryin)
68*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 1
69*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 0
70*67e74705SXin Li   // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
71*67e74705SXin Li   // CHECK: %{{.+}} = zext i1 %{{.+}} to [[UL]]
72*67e74705SXin Li   // CHECK: store [[UL]] %{{.+}}, [[UL]]* %z
73*67e74705SXin Li   unsigned long carryout;
74*67e74705SXin Li   *z = __builtin_addcl(x, y, carryin, &carryout);
75*67e74705SXin Li 
76*67e74705SXin Li   return carryout;
77*67e74705SXin Li }
78*67e74705SXin Li 
test_addcll(unsigned long long x,unsigned long long y,unsigned long long carryin,unsigned long long * z)79*67e74705SXin Li unsigned long long test_addcll(unsigned long long x, unsigned long long y,
80*67e74705SXin Li                                unsigned long long carryin,
81*67e74705SXin Li                                unsigned long long *z) {
82*67e74705SXin Li   // CHECK: @test_addcll
83*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x, i64 %y)
84*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 1
85*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 0
86*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %{{.+}}, i64 %carryin)
87*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 1
88*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 0
89*67e74705SXin Li   // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
90*67e74705SXin Li   // CHECK: %{{.+}} = zext i1 %{{.+}} to i64
91*67e74705SXin Li   // CHECK: store i64 %{{.+}}, i64* %z
92*67e74705SXin Li   unsigned long long carryout;
93*67e74705SXin Li   *z = __builtin_addcll(x, y, carryin, &carryout);
94*67e74705SXin Li 
95*67e74705SXin Li   return carryout;
96*67e74705SXin Li }
97*67e74705SXin Li 
test_subcb(unsigned char x,unsigned char y,unsigned char carryin,unsigned char * z)98*67e74705SXin Li unsigned char test_subcb(unsigned char x, unsigned char y,
99*67e74705SXin Li                          unsigned char carryin, unsigned char *z) {
100*67e74705SXin Li   // CHECK: @test_subcb
101*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %x, i8 %y)
102*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 1
103*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 0
104*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %{{.+}}, i8 %carryin)
105*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 1
106*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 0
107*67e74705SXin Li   // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
108*67e74705SXin Li   // CHECK: %{{.+}} = zext i1 %{{.+}} to i8
109*67e74705SXin Li   // CHECK: store i8 %{{.+}}, i8* %z, align 1
110*67e74705SXin Li 
111*67e74705SXin Li   unsigned char carryout;
112*67e74705SXin Li   *z = __builtin_subcb(x, y, carryin, &carryout);
113*67e74705SXin Li 
114*67e74705SXin Li   return carryout;
115*67e74705SXin Li }
116*67e74705SXin Li 
test_subcs(unsigned short x,unsigned short y,unsigned short carryin,unsigned short * z)117*67e74705SXin Li unsigned short test_subcs(unsigned short x, unsigned short y,
118*67e74705SXin Li                           unsigned short carryin, unsigned short *z) {
119*67e74705SXin Li   // CHECK: @test_subcs
120*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i16, i1 } @llvm.usub.with.overflow.i16(i16 %x, i16 %y)
121*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 1
122*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 0
123*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i16, i1 } @llvm.usub.with.overflow.i16(i16 %{{.+}}, i16 %carryin)
124*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 1
125*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i16, i1 } %{{.+}}, 0
126*67e74705SXin Li   // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
127*67e74705SXin Li   // CHECK: %{{.+}} = zext i1 %{{.+}} to i16
128*67e74705SXin Li   // CHECK: store i16 %{{.+}}, i16* %z, align 2
129*67e74705SXin Li 
130*67e74705SXin Li   unsigned short carryout;
131*67e74705SXin Li   *z = __builtin_subcs(x, y, carryin, &carryout);
132*67e74705SXin Li 
133*67e74705SXin Li   return carryout;
134*67e74705SXin Li }
135*67e74705SXin Li 
test_subc(unsigned x,unsigned y,unsigned carryin,unsigned * z)136*67e74705SXin Li unsigned test_subc(unsigned x, unsigned y, unsigned carryin, unsigned *z) {
137*67e74705SXin Li   // CHECK: @test_subc
138*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
139*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 1
140*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 0
141*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %carryin)
142*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 1
143*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i32, i1 } %{{.+}}, 0
144*67e74705SXin Li   // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
145*67e74705SXin Li   // CHECK: %{{.+}} = zext i1 %{{.+}} to i32
146*67e74705SXin Li   // CHECK: store i32 %{{.+}}, i32* %z, align 4
147*67e74705SXin Li   unsigned carryout;
148*67e74705SXin Li   *z = __builtin_subc(x, y, carryin, &carryout);
149*67e74705SXin Li 
150*67e74705SXin Li   return carryout;
151*67e74705SXin Li }
152*67e74705SXin Li 
test_subcl(unsigned long x,unsigned long y,unsigned long carryin,unsigned long * z)153*67e74705SXin Li unsigned long test_subcl(unsigned long x, unsigned long y,
154*67e74705SXin Li                          unsigned long carryin, unsigned long *z) {
155*67e74705SXin Li   // CHECK: @test_subcl([[UL:i32|i64]] %x
156*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { [[UL]], i1 } @llvm.usub.with.overflow.[[UL]]([[UL]] %x, [[UL]] %y)
157*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 1
158*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 0
159*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { [[UL]], i1 } @llvm.usub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %carryin)
160*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 1
161*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { [[UL]], i1 } %{{.+}}, 0
162*67e74705SXin Li   // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
163*67e74705SXin Li   // CHECK: %{{.+}} = zext i1 %{{.+}} to [[UL]]
164*67e74705SXin Li   // CHECK: store [[UL]] %{{.+}}, [[UL]]* %z
165*67e74705SXin Li   unsigned long carryout;
166*67e74705SXin Li   *z = __builtin_subcl(x, y, carryin, &carryout);
167*67e74705SXin Li 
168*67e74705SXin Li   return carryout;
169*67e74705SXin Li }
170*67e74705SXin Li 
test_subcll(unsigned long long x,unsigned long long y,unsigned long long carryin,unsigned long long * z)171*67e74705SXin Li unsigned long long test_subcll(unsigned long long x, unsigned long long y,
172*67e74705SXin Li                                unsigned long long carryin,
173*67e74705SXin Li                                unsigned long long *z) {
174*67e74705SXin Li   // CHECK: @test_subcll
175*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %x, i64 %y)
176*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 1
177*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 0
178*67e74705SXin Li   // CHECK: %{{.+}} = {{.*}} call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %{{.+}}, i64 %carryin)
179*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 1
180*67e74705SXin Li   // CHECK: %{{.+}} = extractvalue { i64, i1 } %{{.+}}, 0
181*67e74705SXin Li   // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
182*67e74705SXin Li   // CHECK: %{{.+}} = zext i1 %{{.+}} to i64
183*67e74705SXin Li   // CHECK: store i64 %{{.+}}, i64* %z
184*67e74705SXin Li   unsigned long long carryout;
185*67e74705SXin Li   *z = __builtin_subcll(x, y, carryin, &carryout);
186*67e74705SXin Li 
187*67e74705SXin Li   return carryout;
188*67e74705SXin Li }
189