blob: 986e9b2dcedcce75f6b10d794aaccaf986415551 [file] [log] [blame]
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s
unsigned up0() {
unsigned a = 1;
return +a;
}
// CHECK: cir.func @_Z3up0v() -> !u32i
// CHECK: %[[#RET:]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["__retval"]
// CHECK: %[[#A:]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init]
// CHECK: %[[#INPUT:]] = cir.load %[[#A]]
// CHECK: %[[#OUTPUT:]] = cir.unary(plus, %[[#INPUT]])
// CHECK: cir.store %[[#OUTPUT]], %[[#RET]]
unsigned um0() {
unsigned a = 1;
return -a;
}
// CHECK: cir.func @_Z3um0v() -> !u32i
// CHECK: %[[#RET:]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["__retval"]
// CHECK: %[[#A:]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init]
// CHECK: %[[#INPUT:]] = cir.load %[[#A]]
// CHECK: %[[#OUTPUT:]] = cir.unary(minus, %[[#INPUT]])
// CHECK: cir.store %[[#OUTPUT]], %[[#RET]]
unsigned un0() {
unsigned a = 1;
return ~a; // a ^ -1 , not
}
// CHECK: cir.func @_Z3un0v() -> !u32i
// CHECK: %[[#RET:]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["__retval"]
// CHECK: %[[#A:]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init]
// CHECK: %[[#INPUT:]] = cir.load %[[#A]]
// CHECK: %[[#OUTPUT:]] = cir.unary(not, %[[#INPUT]])
// CHECK: cir.store %[[#OUTPUT]], %[[#RET]]
int inc0() {
int a = 1;
++a;
return a;
}
// CHECK: cir.func @_Z4inc0v() -> !s32i
// CHECK: %[[#RET:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
// CHECK: %[[#A:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
// CHECK: %[[#ATMP:]] = cir.const #cir.int<1> : !s32i
// CHECK: cir.store %[[#ATMP]], %[[#A]] : !s32i
// CHECK: %[[#INPUT:]] = cir.load %[[#A]]
// CHECK: %[[#INCREMENTED:]] = cir.unary(inc, %[[#INPUT]])
// CHECK: cir.store %[[#INCREMENTED]], %[[#A]]
// CHECK: %[[#A_TO_OUTPUT:]] = cir.load %[[#A]]
// CHECK: cir.store %[[#A_TO_OUTPUT]], %[[#RET]]
// CHECK: %[[#OUTPUT:]] = cir.load %[[#RET]]
// CHECK: cir.return %[[#OUTPUT]] : !s32i
int dec0() {
int a = 1;
--a;
return a;
}
// CHECK: cir.func @_Z4dec0v() -> !s32i
// CHECK: %[[#RET:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
// CHECK: %[[#A:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
// CHECK: %[[#ATMP:]] = cir.const #cir.int<1> : !s32i
// CHECK: cir.store %[[#ATMP]], %[[#A]] : !s32i
// CHECK: %[[#INPUT:]] = cir.load %[[#A]]
// CHECK: %[[#INCREMENTED:]] = cir.unary(dec, %[[#INPUT]])
// CHECK: cir.store %[[#INCREMENTED]], %[[#A]]
// CHECK: %[[#A_TO_OUTPUT:]] = cir.load %[[#A]]
// CHECK: cir.store %[[#A_TO_OUTPUT]], %[[#RET]]
// CHECK: %[[#OUTPUT:]] = cir.load %[[#RET]]
// CHECK: cir.return %[[#OUTPUT]] : !s32i
int inc1() {
int a = 1;
a++;
return a;
}
// CHECK: cir.func @_Z4inc1v() -> !s32i
// CHECK: %[[#RET:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
// CHECK: %[[#A:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
// CHECK: %[[#ATMP:]] = cir.const #cir.int<1> : !s32i
// CHECK: cir.store %[[#ATMP]], %[[#A]] : !s32i
// CHECK: %[[#INPUT:]] = cir.load %[[#A]]
// CHECK: %[[#INCREMENTED:]] = cir.unary(inc, %[[#INPUT]])
// CHECK: cir.store %[[#INCREMENTED]], %[[#A]]
// CHECK: %[[#A_TO_OUTPUT:]] = cir.load %[[#A]]
// CHECK: cir.store %[[#A_TO_OUTPUT]], %[[#RET]]
// CHECK: %[[#OUTPUT:]] = cir.load %[[#RET]]
// CHECK: cir.return %[[#OUTPUT]] : !s32i
int dec1() {
int a = 1;
a--;
return a;
}
// CHECK: cir.func @_Z4dec1v() -> !s32i
// CHECK: %[[#RET:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
// CHECK: %[[#A:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
// CHECK: %[[#ATMP:]] = cir.const #cir.int<1> : !s32i
// CHECK: cir.store %[[#ATMP]], %[[#A]] : !s32i
// CHECK: %[[#INPUT:]] = cir.load %[[#A]]
// CHECK: %[[#INCREMENTED:]] = cir.unary(dec, %[[#INPUT]])
// CHECK: cir.store %[[#INCREMENTED]], %[[#A]]
// CHECK: %[[#A_TO_OUTPUT:]] = cir.load %[[#A]]
// CHECK: cir.store %[[#A_TO_OUTPUT]], %[[#RET]]
// CHECK: %[[#OUTPUT:]] = cir.load %[[#RET]]
// CHECK: cir.return %[[#OUTPUT]] : !s32i
// Ensure the increment is performed after the assignment to b.
int inc2() {
int a = 1;
int b = a++;
return b;
}
// CHECK: cir.func @_Z4inc2v() -> !s32i
// CHECK: %[[#RET:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
// CHECK: %[[#A:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
// CHECK: %[[#B:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
// CHECK: %[[#ATMP:]] = cir.const #cir.int<1> : !s32i
// CHECK: cir.store %[[#ATMP]], %[[#A]] : !s32i
// CHECK: %[[#ATOB:]] = cir.load %[[#A]]
// CHECK: %[[#INCREMENTED:]] = cir.unary(inc, %[[#ATOB]])
// CHECK: cir.store %[[#INCREMENTED]], %[[#A]]
// CHECK: cir.store %[[#ATOB]], %[[#B]]
// CHECK: %[[#B_TO_OUTPUT:]] = cir.load %[[#B]]
// CHECK: cir.store %[[#B_TO_OUTPUT]], %[[#RET]]
// CHECK: %[[#OUTPUT:]] = cir.load %[[#RET]]
// CHECK: cir.return %[[#OUTPUT]] : !s32i
int *inc_p(int *i) {
--i;
++i;
return i;
}
// CHECK: cir.func @_Z5inc_pPi(%arg0: !cir.ptr<!s32i>
// CHECK: %[[#i_addr:]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["i", init] {alignment = 8 : i64}
// CHECK: %[[#i_dec:]] = cir.load %[[#i_addr]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
// CHECK: %[[#dec_const:]] = cir.const #cir.int<-1> : !s32i
// CHECK: = cir.ptr_stride(%[[#i_dec]] : !cir.ptr<!s32i>, %[[#dec_const]] : !s32i), !cir.ptr<!s32i>
// CHECK: %[[#i_inc:]] = cir.load %0 : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
// CHECK: %[[#inc_const:]] = cir.const #cir.int<1> : !s32i
// CHECK: = cir.ptr_stride(%[[#i_inc]] : !cir.ptr<!s32i>, %[[#inc_const]] : !s32i), !cir.ptr<!s32i>
void floats(float f) {
// CHECK: cir.func @{{.+}}floats{{.+}}
f = +f; // CHECK: %{{[0-9]+}} = cir.unary(plus, %{{[0-9]+}}) : !cir.float, !cir.float
f = -f; // CHECK: %{{[0-9]+}} = cir.unary(minus, %{{[0-9]+}}) : !cir.float, !cir.float
++f; // CHECK: = cir.unary(inc, %{{[0-9]+}}) : !cir.float, !cir.float
--f; // CHECK: = cir.unary(dec, %{{[0-9]+}}) : !cir.float, !cir.float
f++; // CHECK: = cir.unary(inc, %{{[0-9]+}}) : !cir.float, !cir.float
f--; // CHECK: = cir.unary(dec, %{{[0-9]+}}) : !cir.float, !cir.float
f = !f;
// CHECK: %[[#F_BOOL:]] = cir.cast(float_to_bool, %{{[0-9]+}} : !cir.float), !cir.bool
// CHECK: = cir.unary(not, %[[#F_BOOL]]) : !cir.bool, !cir.bool
}
void doubles(double d) {
// CHECK: cir.func @{{.+}}doubles{{.+}}
d = +d; // CHECK: %{{[0-9]+}} = cir.unary(plus, %{{[0-9]+}}) : !cir.double, !cir.double
d = -d; // CHECK: %{{[0-9]+}} = cir.unary(minus, %{{[0-9]+}}) : !cir.double, !cir.double
++d; // CHECK: = cir.unary(inc, %{{[0-9]+}}) : !cir.double, !cir.double
--d; // CHECK: = cir.unary(dec, %{{[0-9]+}}) : !cir.double, !cir.double
d++; // CHECK: = cir.unary(inc, %{{[0-9]+}}) : !cir.double, !cir.double
d--; // CHECK: = cir.unary(dec, %{{[0-9]+}}) : !cir.double, !cir.double
d = !d;
// CHECK: %[[#D_BOOL:]] = cir.cast(float_to_bool, %{{[0-9]+}} : !cir.double), !cir.bool
// CHECK: = cir.unary(not, %[[#D_BOOL]]) : !cir.bool, !cir.bool
}
void pointers(int *p) {
// CHECK: cir.func @{{[^ ]+}}pointers
// CHECK: %[[#P:]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
p = +p;
// CHECK: cir.unary(plus, %{{.+}}) : !cir.ptr<!s32i>, !cir.ptr<!s32i>
++p;
// CHECK: %[[#INC:]] = cir.const #cir.int<1> : !s32i
// CHECK: %[[#RES:]] = cir.ptr_stride(%{{.+}} : !cir.ptr<!s32i>, %[[#INC]] : !s32i), !cir.ptr<!s32i>
// CHECK: cir.store %[[#RES]], %[[#P]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
--p;
// CHECK: %[[#DEC:]] = cir.const #cir.int<-1> : !s32i
// CHECK: %[[#RES:]] = cir.ptr_stride(%{{.+}} : !cir.ptr<!s32i>, %[[#DEC]] : !s32i), !cir.ptr<!s32i>
// CHECK: cir.store %[[#RES]], %[[#P]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
p++;
// CHECK: %[[#INC:]] = cir.const #cir.int<1> : !s32i
// CHECK: %[[#RES:]] = cir.ptr_stride(%{{.+}} : !cir.ptr<!s32i>, %[[#INC]] : !s32i), !cir.ptr<!s32i>
// CHECK: cir.store %[[#RES]], %[[#P]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
p--;
// CHECK: %[[#DEC:]] = cir.const #cir.int<-1> : !s32i
// CHECK: %[[#RES:]] = cir.ptr_stride(%{{.+}} : !cir.ptr<!s32i>, %[[#DEC]] : !s32i), !cir.ptr<!s32i>
// CHECK: cir.store %[[#RES]], %[[#P]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
bool p1 = !p;
// %[[BOOLPTR:]] = cir.cast(ptr_to_bool, %15 : !cir.ptr<!s32i>), !cir.bool
// cir.unary(not, %[[BOOLPTR]]) : !cir.bool, !cir.bool
}
void chars(char c) {
// CHECK: cir.func @{{.+}}chars{{.+}}
int c1 = +c;
// CHECK: %[[#PROMO:]] = cir.cast(integral, %{{.+}} : !s8i), !s32i
// CHECK: cir.unary(plus, %[[#PROMO]]) : !s32i, !s32i
int c2 = -c;
// CHECK: %[[#PROMO:]] = cir.cast(integral, %{{.+}} : !s8i), !s32i
// CHECK: cir.unary(minus, %[[#PROMO]]) : !s32i, !s32i
// Chars can go through some integer promotion codegen paths even when not promoted.
++c; // CHECK: cir.unary(inc, %10) : !s8i, !s8i
--c; // CHECK: cir.unary(dec, %12) : !s8i, !s8i
c++; // CHECK: cir.unary(inc, %14) : !s8i, !s8i
c--; // CHECK: cir.unary(dec, %16) : !s8i, !s8i
bool c3 = !c;
// CHECK: %[[#C_BOOL:]] = cir.cast(int_to_bool, %{{[0-9]+}} : !s8i), !cir.bool
// CHECK: cir.unary(not, %[[#C_BOOL]]) : !cir.bool, !cir.bool
}