625 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-cir %s -o %t.cir2// RUN: FileCheck --input-file=%t.cir %s3// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-llvm %s -o %t-cir.ll4// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM5// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll6// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG7 8unsigned up0() {9 unsigned a = 1u;10 return +a;11}12 13// CHECK: cir.func{{.*}} @_Z3up0v() -> !u32i14// CHECK: %[[A:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init]15// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]16// CHECK: %[[OUTPUT:.*]] = cir.unary(plus, %[[INPUT]])17 18// LLVM: define{{.*}} i32 @_Z3up0v()19// LLVM: %[[RV:.*]] = alloca i32, i64 1, align 420// LLVM: %[[A:.*]] = alloca i32, i64 1, align 421// LLVM: store i32 1, ptr %[[A]], align 422// LLVM: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 423 24// OGCG: define{{.*}} i32 @_Z3up0v()25// OGCG: %[[A:.*]] = alloca i32, align 426// OGCG: store i32 1, ptr %[[A]], align 427// OGCG: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 428 29unsigned um0() {30 unsigned a = 1u;31 return -a;32}33 34// CHECK: cir.func{{.*}} @_Z3um0v() -> !u32i35// CHECK: %[[A:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init]36// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]37// CHECK: %[[OUTPUT:.*]] = cir.unary(minus, %[[INPUT]])38 39// LLVM: define{{.*}} i32 @_Z3um0v()40// LLVM: %[[RV:.*]] = alloca i32, i64 1, align 441// LLVM: %[[A:.*]] = alloca i32, i64 1, align 442// LLVM: store i32 1, ptr %[[A]], align 443// LLVM: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 444// LLVM: %[[RESULT:.*]] = sub i32 0, %[[A_LOAD]]45 46// OGCG: define{{.*}} i32 @_Z3um0v()47// OGCG: %[[A:.*]] = alloca i32, align 448// OGCG: store i32 1, ptr %[[A]], align 449// OGCG: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 450// OGCG: %[[RESULT:.*]] = sub i32 0, %[[A_LOAD]]51 52unsigned un0() {53 unsigned a = 1u;54 return ~a; // a ^ -1 , not55}56 57// CHECK: cir.func{{.*}} @_Z3un0v() -> !u32i58// CHECK: %[[A:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init]59// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]60// CHECK: %[[OUTPUT:.*]] = cir.unary(not, %[[INPUT]])61 62// LLVM: define{{.*}} i32 @_Z3un0v()63// LLVM: %[[RV:.*]] = alloca i32, i64 1, align 464// LLVM: %[[A:.*]] = alloca i32, i64 1, align 465// LLVM: store i32 1, ptr %[[A]], align 466// LLVM: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 467// LLVM: %[[RESULT:.*]] = xor i32 %[[A_LOAD]], -168 69// OGCG: define{{.*}} i32 @_Z3un0v()70// OGCG: %[[A:.*]] = alloca i32, align 471// OGCG: store i32 1, ptr %[[A]], align 472// OGCG: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 473// OGCG: %[[RESULT:.*]] = xor i32 %[[A_LOAD]], -174 75int inc0() {76 int a = 1;77 ++a;78 return a;79}80 81// CHECK: cir.func{{.*}} @_Z4inc0v() -> !s32i82// CHECK: %[[A:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]83// CHECK: %[[ATMP:.*]] = cir.const #cir.int<1> : !s32i84// CHECK: cir.store{{.*}} %[[ATMP]], %[[A]] : !s32i85// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]86// CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[INPUT]]) nsw87// CHECK: cir.store{{.*}} %[[INCREMENTED]], %[[A]]88// CHECK: %[[A_TO_OUTPUT:.*]] = cir.load{{.*}} %[[A]]89 90// LLVM: define{{.*}} i32 @_Z4inc0v()91// LLVM: %[[RV:.*]] = alloca i32, i64 1, align 492// LLVM: %[[A:.*]] = alloca i32, i64 1, align 493// LLVM: store i32 1, ptr %[[A]], align 494// LLVM: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 495// LLVM: %[[RESULT:.*]] = add nsw i32 %[[A_LOAD]], 196 97// OGCG: define{{.*}} i32 @_Z4inc0v()98// OGCG: %[[A:.*]] = alloca i32, align 499// OGCG: store i32 1, ptr %[[A]], align 4100// OGCG: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 4101// OGCG: %[[RESULT:.*]] = add nsw i32 %[[A_LOAD]], 1102 103int dec0() {104 int a = 1;105 --a;106 return a;107}108 109// CHECK: cir.func{{.*}} @_Z4dec0v() -> !s32i110// CHECK: %[[A:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]111// CHECK: %[[ATMP:.*]] = cir.const #cir.int<1> : !s32i112// CHECK: cir.store{{.*}} %[[ATMP]], %[[A]] : !s32i113// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]114// CHECK: %[[DECREMENTED:.*]] = cir.unary(dec, %[[INPUT]]) nsw115// CHECK: cir.store{{.*}} %[[DECREMENTED]], %[[A]]116// CHECK: %[[A_TO_OUTPUT:.*]] = cir.load{{.*}} %[[A]]117 118// LLVM: define{{.*}} i32 @_Z4dec0v()119// LLVM: %[[RV:.*]] = alloca i32, i64 1, align 4120// LLVM: %[[A:.*]] = alloca i32, i64 1, align 4121// LLVM: store i32 1, ptr %[[A]], align 4122// LLVM: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 4123// LLVM: %[[RESULT:.*]] = sub nsw i32 %[[A_LOAD]], 1124 125// OGCG: define{{.*}} i32 @_Z4dec0v()126// OGCG: %[[A:.*]] = alloca i32, align 4127// OGCG: store i32 1, ptr %[[A]], align 4128// OGCG: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 4129// OGCG: %[[RESULT:.*]] = add nsw i32 %[[A_LOAD]], -1130 131int inc1() {132 int a = 1;133 a++;134 return a;135}136 137// CHECK: cir.func{{.*}} @_Z4inc1v() -> !s32i138// CHECK: %[[A:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]139// CHECK: %[[ATMP:.*]] = cir.const #cir.int<1> : !s32i140// CHECK: cir.store{{.*}} %[[ATMP]], %[[A]] : !s32i141// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]142// CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[INPUT]]) nsw143// CHECK: cir.store{{.*}} %[[INCREMENTED]], %[[A]]144// CHECK: %[[A_TO_OUTPUT:.*]] = cir.load{{.*}} %[[A]]145 146// LLVM: define{{.*}} i32 @_Z4inc1v()147// LLVM: %[[RV:.*]] = alloca i32, i64 1, align 4148// LLVM: %[[A:.*]] = alloca i32, i64 1, align 4149// LLVM: store i32 1, ptr %[[A]], align 4150// LLVM: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 4151// LLVM: %[[RESULT:.*]] = add nsw i32 %[[A_LOAD]], 1152 153// OGCG: define{{.*}} i32 @_Z4inc1v()154// OGCG: %[[A:.*]] = alloca i32, align 4155// OGCG: store i32 1, ptr %[[A]], align 4156// OGCG: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 4157// OGCG: %[[RESULT:.*]] = add nsw i32 %[[A_LOAD]], 1158 159int dec1() {160 int a = 1;161 a--;162 return a;163}164 165// CHECK: cir.func{{.*}} @_Z4dec1v() -> !s32i166// CHECK: %[[A:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]167// CHECK: %[[ATMP:.*]] = cir.const #cir.int<1> : !s32i168// CHECK: cir.store{{.*}} %[[ATMP]], %[[A]] : !s32i169// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]170// CHECK: %[[DECREMENTED:.*]] = cir.unary(dec, %[[INPUT]]) nsw171// CHECK: cir.store{{.*}} %[[DECREMENTED]], %[[A]]172// CHECK: %[[A_TO_OUTPUT:.*]] = cir.load{{.*}} %[[A]]173 174// LLVM: define{{.*}} i32 @_Z4dec1v()175// LLVM: %[[RV:.*]] = alloca i32, i64 1, align 4176// LLVM: %[[A:.*]] = alloca i32, i64 1, align 4177// LLVM: store i32 1, ptr %[[A]], align 4178// LLVM: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 4179// LLVM: %[[RESULT:.*]] = sub nsw i32 %[[A_LOAD]], 1180 181// OGCG: define{{.*}} i32 @_Z4dec1v()182// OGCG: %[[A:.*]] = alloca i32, align 4183// OGCG: store i32 1, ptr %[[A]], align 4184// OGCG: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 4185// OGCG: %[[RESULT:.*]] = add nsw i32 %[[A_LOAD]], -1186 187// Ensure the increment is performed after the assignment to b.188int inc2() {189 int a = 1;190 int b = a++;191 return b;192}193 194// CHECK: cir.func{{.*}} @_Z4inc2v() -> !s32i195// CHECK: %[[A:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]196// CHECK: %[[B:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]197// CHECK: %[[ATMP:.*]] = cir.const #cir.int<1> : !s32i198// CHECK: cir.store{{.*}} %[[ATMP]], %[[A]] : !s32i199// CHECK: %[[ATOB:.*]] = cir.load{{.*}} %[[A]]200// CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[ATOB]]) nsw201// CHECK: cir.store{{.*}} %[[INCREMENTED]], %[[A]]202// CHECK: cir.store{{.*}} %[[ATOB]], %[[B]]203// CHECK: %[[B_TO_OUTPUT:.*]] = cir.load{{.*}} %[[B]]204 205// LLVM: define{{.*}} i32 @_Z4inc2v()206// LLVM: %[[RV:.*]] = alloca i32, i64 1, align 4207// LLVM: %[[A:.*]] = alloca i32, i64 1, align 4208// LLVM: %[[B:.*]] = alloca i32, i64 1, align 4209// LLVM: store i32 1, ptr %[[A]], align 4210// LLVM: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 4211// LLVM: %[[A_INC:.*]] = add nsw i32 %[[A_LOAD]], 1212// LLVM: store i32 %[[A_INC]], ptr %[[A]], align 4213// LLVM: store i32 %[[A_LOAD]], ptr %[[B]], align 4214// LLVM: %[[B_TO_OUTPUT:.*]] = load i32, ptr %[[B]], align 4215 216// OGCG: define{{.*}} i32 @_Z4inc2v()217// OGCG: %[[A:.*]] = alloca i32, align 4218// OGCG: %[[B:.*]] = alloca i32, align 4219// OGCG: store i32 1, ptr %[[A]], align 4220// OGCG: %[[A_LOAD:.*]] = load i32, ptr %[[A]], align 4221// OGCG: %[[A_INC:.*]] = add nsw i32 %[[A_LOAD]], 1222// OGCG: store i32 %[[A_INC]], ptr %[[A]], align 4223// OGCG: store i32 %[[A_LOAD]], ptr %[[B]], align 4224// OGCG: %[[B_TO_OUTPUT:.*]] = load i32, ptr %[[B]], align 4225 226float fpPlus() {227 float a = 1.0f;228 return +a;229}230 231// CHECK: cir.func{{.*}} @_Z6fpPlusv() -> !cir.float232// CHECK: %[[A:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a", init]233// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]234// CHECK: %[[OUTPUT:.*]] = cir.unary(plus, %[[INPUT]])235 236// LLVM: define{{.*}} float @_Z6fpPlusv()237// LLVM: %[[RV:.*]] = alloca float, i64 1, align 4238// LLVM: %[[A:.*]] = alloca float, i64 1, align 4239// LLVM: store float 1.000000e+00, ptr %[[A]], align 4240// LLVM: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4241 242// OGCG: define{{.*}} float @_Z6fpPlusv()243// OGCG: %[[A:.*]] = alloca float, align 4244// OGCG: store float 1.000000e+00, ptr %[[A]], align 4245// OGCG: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4246 247float fpMinus() {248 float a = 1.0f;249 return -a;250}251 252// CHECK: cir.func{{.*}} @_Z7fpMinusv() -> !cir.float253// CHECK: %[[A:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a", init]254// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]255// CHECK: %[[OUTPUT:.*]] = cir.unary(minus, %[[INPUT]])256 257// LLVM: define{{.*}} float @_Z7fpMinusv()258// LLVM: %[[RV:.*]] = alloca float, i64 1, align 4259// LLVM: %[[A:.*]] = alloca float, i64 1, align 4260// LLVM: store float 1.000000e+00, ptr %[[A]], align 4261// LLVM: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4262// LLVM: %[[RESULT:.*]] = fneg float %[[A_LOAD]]263 264// OGCG: define{{.*}} float @_Z7fpMinusv()265// OGCG: %[[A:.*]] = alloca float, align 4266// OGCG: store float 1.000000e+00, ptr %[[A]], align 4267// OGCG: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4268// OGCG: %[[RESULT:.*]] = fneg float %[[A_LOAD]]269 270float fpPreInc() {271 float a = 1.0f;272 return ++a;273}274 275// CHECK: cir.func{{.*}} @_Z8fpPreIncv() -> !cir.float276// CHECK: %[[A:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a", init]277// CHECK: %[[ATMP:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float278// CHECK: cir.store{{.*}} %[[ATMP]], %[[A]] : !cir.float279// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]280// CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[INPUT]])281 282// LLVM: define{{.*}} float @_Z8fpPreIncv()283// LLVM: %[[RV:.*]] = alloca float, i64 1, align 4284// LLVM: %[[A:.*]] = alloca float, i64 1, align 4285// LLVM: store float 1.000000e+00, ptr %[[A]], align 4286// LLVM: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4287// LLVM: %[[RESULT:.*]] = fadd float 1.000000e+00, %[[A_LOAD]]288 289// OGCG: define{{.*}} float @_Z8fpPreIncv()290// OGCG: %[[A:.*]] = alloca float, align 4291// OGCG: store float 1.000000e+00, ptr %[[A]], align 4292// OGCG: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4293// OGCG: %[[RESULT:.*]] = fadd float %[[A_LOAD]], 1.000000e+00294 295float fpPreDec() {296 float a = 1.0f;297 return --a;298}299 300// CHECK: cir.func{{.*}} @_Z8fpPreDecv() -> !cir.float301// CHECK: %[[A:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a", init]302// CHECK: %[[ATMP:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float303// CHECK: cir.store{{.*}} %[[ATMP]], %[[A]] : !cir.float304// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]305// CHECK: %[[DECREMENTED:.*]] = cir.unary(dec, %[[INPUT]])306 307// LLVM: define{{.*}} float @_Z8fpPreDecv()308// LLVM: %[[RV:.*]] = alloca float, i64 1, align 4309// LLVM: %[[A:.*]] = alloca float, i64 1, align 4310// LLVM: store float 1.000000e+00, ptr %[[A]], align 4311// LLVM: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4312// LLVM: %[[RESULT:.*]] = fadd float -1.000000e+00, %[[A_LOAD]]313 314// OGCG: define{{.*}} float @_Z8fpPreDecv()315// OGCG: %[[A:.*]] = alloca float, align 4316// OGCG: store float 1.000000e+00, ptr %[[A]], align 4317// OGCG: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4318// OGCG: %[[RESULT:.*]] = fadd float %[[A_LOAD]], -1.000000e+00319 320float fpPostInc() {321 float a = 1.0f;322 return a++;323}324 325// CHECK: cir.func{{.*}} @_Z9fpPostIncv() -> !cir.float326// CHECK: %[[A:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a", init]327// CHECK: %[[ATMP:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float328// CHECK: cir.store{{.*}} %[[ATMP]], %[[A]] : !cir.float329// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]330// CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[INPUT]])331 332// LLVM: define{{.*}} float @_Z9fpPostIncv()333// LLVM: %[[RV:.*]] = alloca float, i64 1, align 4334// LLVM: %[[A:.*]] = alloca float, i64 1, align 4335// LLVM: store float 1.000000e+00, ptr %[[A]], align 4336// LLVM: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4337// LLVM: %[[RESULT:.*]] = fadd float 1.000000e+00, %[[A_LOAD]]338 339// OGCG: define{{.*}} float @_Z9fpPostIncv()340// OGCG: %[[A:.*]] = alloca float, align 4341// OGCG: store float 1.000000e+00, ptr %[[A]], align 4342// OGCG: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4343// OGCG: %[[RESULT:.*]] = fadd float %[[A_LOAD]], 1.000000e+00344 345float fpPostDec() {346 float a = 1.0f;347 return a--;348}349 350// CHECK: cir.func{{.*}} @_Z9fpPostDecv() -> !cir.float351// CHECK: %[[A:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a", init]352// CHECK: %[[ATMP:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float353// CHECK: cir.store{{.*}} %[[ATMP]], %[[A]] : !cir.float354// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[A]]355// CHECK: %[[DECREMENTED:.*]] = cir.unary(dec, %[[INPUT]])356 357// LLVM: define{{.*}} float @_Z9fpPostDecv()358// LLVM: %[[RV:.*]] = alloca float, i64 1, align 4359// LLVM: %[[A:.*]] = alloca float, i64 1, align 4360// LLVM: store float 1.000000e+00, ptr %[[A]], align 4361// LLVM: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4362// LLVM: %[[RESULT:.*]] = fadd float -1.000000e+00, %[[A_LOAD]]363 364// OGCG: define{{.*}} float @_Z9fpPostDecv()365// OGCG: %[[A:.*]] = alloca float, align 4366// OGCG: store float 1.000000e+00, ptr %[[A]], align 4367// OGCG: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4368// OGCG: %[[RESULT:.*]] = fadd float %[[A_LOAD]], -1.000000e+00369 370// Ensure the increment is performed after the assignment to b.371float fpPostInc2() {372 float a = 1.0f;373 float b = a++;374 return b;375}376 377// CHECK: cir.func{{.*}} @_Z10fpPostInc2v() -> !cir.float378// CHECK: %[[A:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a", init]379// CHECK: %[[B:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["b", init]380// CHECK: %[[ATMP:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float381// CHECK: cir.store{{.*}} %[[ATMP]], %[[A]] : !cir.float382// CHECK: %[[ATOB:.*]] = cir.load{{.*}} %[[A]]383// CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[ATOB]])384// CHECK: cir.store{{.*}} %[[INCREMENTED]], %[[A]]385// CHECK: cir.store{{.*}} %[[ATOB]], %[[B]]386// CHECK: %[[B_TO_OUTPUT:.*]] = cir.load{{.*}} %[[B]]387 388// LLVM: define{{.*}} float @_Z10fpPostInc2v()389// LLVM: %[[RV:.*]] = alloca float, i64 1, align 4390// LLVM: %[[A:.*]] = alloca float, i64 1, align 4391// LLVM: %[[B:.*]] = alloca float, i64 1, align 4392// LLVM: store float 1.000000e+00, ptr %[[A]], align 4393// LLVM: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4394// LLVM: %[[A_INC:.*]] = fadd float 1.000000e+00, %[[A_LOAD]]395// LLVM: store float %[[A_INC]], ptr %[[A]], align 4396// LLVM: store float %[[A_LOAD]], ptr %[[B]], align 4397// LLVM: %[[B_TO_OUTPUT:.*]] = load float, ptr %[[B]], align 4398 399// OGCG: define{{.*}} float @_Z10fpPostInc2v()400// OGCG: %[[A:.*]] = alloca float, align 4401// OGCG: %[[B:.*]] = alloca float, align 4402// OGCG: store float 1.000000e+00, ptr %[[A]], align 4403// OGCG: %[[A_LOAD:.*]] = load float, ptr %[[A]], align 4404// OGCG: %[[A_INC:.*]] = fadd float %[[A_LOAD]], 1.000000e+00405// OGCG: store float %[[A_INC]], ptr %[[A]], align 4406// OGCG: store float %[[A_LOAD]], ptr %[[B]], align 4407// OGCG: %[[B_TO_OUTPUT:.*]] = load float, ptr %[[B]], align 4408 409void chars(char c) {410// CHECK: cir.func{{.*}} @_Z5charsc411 412 int c1 = +c;413 // CHECK: %[[PROMO:.*]] = cir.cast integral %{{.+}} : !s8i -> !s32i414 // CHECK: cir.unary(plus, %[[PROMO]]) : !s32i, !s32i415 int c2 = -c;416 // CHECK: %[[PROMO:.*]] = cir.cast integral %{{.+}} : !s8i -> !s32i417 // CHECK: cir.unary(minus, %[[PROMO]]) nsw : !s32i, !s32i418 419 // Chars can go through some integer promotion codegen paths even when not promoted.420 // These should not have nsw attributes because the intermediate promotion makes the421 // overflow defined behavior.422 ++c; // CHECK: cir.unary(inc, %{{.+}}) : !s8i, !s8i423 --c; // CHECK: cir.unary(dec, %{{.+}}) : !s8i, !s8i424 c++; // CHECK: cir.unary(inc, %{{.+}}) : !s8i, !s8i425 c--; // CHECK: cir.unary(dec, %{{.+}}) : !s8i, !s8i426}427 428_Float16 fp16UPlus(_Float16 f) {429 return +f;430}431 432// CHECK: cir.func{{.*}} @_Z9fp16UPlusDF16_({{.*}}) -> !cir.f16433// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[F:.*]]434// CHECK: %[[PROMOTED:.*]] = cir.cast floating %[[INPUT]] : !cir.f16 -> !cir.float435// CHECK: %[[RESULT:.*]] = cir.unary(plus, %[[PROMOTED]])436// CHECK: %[[UNPROMOTED:.*]] = cir.cast floating %[[RESULT]] : !cir.float -> !cir.f16437 438// LLVM: define{{.*}} half @_Z9fp16UPlusDF16_({{.*}})439// LLVM: %[[F_LOAD:.*]] = load half, ptr %{{.*}}, align 2440// LLVM: %[[PROMOTED:.*]] = fpext half %[[F_LOAD]] to float441// LLVM: %[[UNPROMOTED:.*]] = fptrunc float %[[PROMOTED]] to half442 443// OGCG: define{{.*}} half @_Z9fp16UPlusDF16_({{.*}})444// OGCG: %[[F_LOAD:.*]] = load half, ptr %{{.*}}, align 2445// OGCG: %[[PROMOTED:.*]] = fpext half %[[F_LOAD]] to float446// OGCG: %[[UNPROMOTED:.*]] = fptrunc float %[[PROMOTED]] to half447 448_Float16 fp16UMinus(_Float16 f) {449 return -f;450}451 452// CHECK: cir.func{{.*}} @_Z10fp16UMinusDF16_({{.*}}) -> !cir.f16453// CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[F:.*]]454// CHECK: %[[PROMOTED:.*]] = cir.cast floating %[[INPUT]] : !cir.f16 -> !cir.float455// CHECK: %[[RESULT:.*]] = cir.unary(minus, %[[PROMOTED]])456// CHECK: %[[UNPROMOTED:.*]] = cir.cast floating %[[RESULT]] : !cir.float -> !cir.f16457 458// LLVM: define{{.*}} half @_Z10fp16UMinusDF16_({{.*}})459// LLVM: %[[F_LOAD:.*]] = load half, ptr %{{.*}}, align 2460// LLVM: %[[PROMOTED:.*]] = fpext half %[[F_LOAD]] to float461// LLVM: %[[RESULT:.*]] = fneg float %[[PROMOTED]]462// LLVM: %[[UNPROMOTED:.*]] = fptrunc float %[[RESULT]] to half463 464// OGCG: define{{.*}} half @_Z10fp16UMinusDF16_({{.*}})465// OGCG: %[[F_LOAD:.*]] = load half, ptr %{{.*}}, align 2466// OGCG: %[[PROMOTED:.*]] = fpext half %[[F_LOAD]] to float467// OGCG: %[[RESULT:.*]] = fneg float %[[PROMOTED]]468// OGCG: %[[UNPROMOTED:.*]] = fptrunc float %[[RESULT]] to half469 470void test_logical_not() {471 int a = 5;472 a = !a;473 bool b = false;474 b = !b;475 float c = 2.0f;476 c = !c;477 int *p = 0;478 b = !p;479 double d = 3.0;480 b = !d;481}482 483// CHECK: cir.func{{.*}} @_Z16test_logical_notv()484// CHECK: %[[A:.*]] = cir.load{{.*}} %[[A_ADDR:.*]] : !cir.ptr<!s32i>, !s32i485// CHECK: %[[A_BOOL:.*]] = cir.cast int_to_bool %[[A]] : !s32i -> !cir.bool486// CHECK: %[[A_NOT:.*]] = cir.unary(not, %[[A_BOOL]]) : !cir.bool, !cir.bool487// CHECK: %[[A_CAST:.*]] = cir.cast bool_to_int %[[A_NOT]] : !cir.bool -> !s32i488// CHECK: cir.store{{.*}} %[[A_CAST]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>489// CHECK: %[[B:.*]] = cir.load{{.*}} %[[B_ADDR:.*]] : !cir.ptr<!cir.bool>, !cir.bool490// CHECK: %[[B_NOT:.*]] = cir.unary(not, %[[B]]) : !cir.bool, !cir.bool491// CHECK: cir.store{{.*}} %[[B_NOT]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>492// CHECK: %[[C:.*]] = cir.load{{.*}} %[[C_ADDR:.*]] : !cir.ptr<!cir.float>, !cir.float493// CHECK: %[[C_BOOL:.*]] = cir.cast float_to_bool %[[C]] : !cir.float -> !cir.bool494// CHECK: %[[C_NOT:.*]] = cir.unary(not, %[[C_BOOL]]) : !cir.bool, !cir.bool495// CHECK: %[[C_CAST:.*]] = cir.cast bool_to_float %[[C_NOT]] : !cir.bool -> !cir.float496// CHECK: cir.store{{.*}} %[[C_CAST]], %[[C_ADDR]] : !cir.float, !cir.ptr<!cir.float>497// CHECK: %[[P:.*]] = cir.load{{.*}} %[[P_ADDR:.*]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>498// CHECK: %[[P_BOOL:.*]] = cir.cast ptr_to_bool %[[P]] : !cir.ptr<!s32i> -> !cir.bool499// CHECK: %[[P_NOT:.*]] = cir.unary(not, %[[P_BOOL]]) : !cir.bool, !cir.bool500// CHECK: cir.store{{.*}} %[[P_NOT]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>501// CHECK: %[[D:.*]] = cir.load{{.*}} %[[D_ADDR:.*]] : !cir.ptr<!cir.double>, !cir.double502// CHECK: %[[D_BOOL:.*]] = cir.cast float_to_bool %[[D]] : !cir.double -> !cir.bool503// CHECK: %[[D_NOT:.*]] = cir.unary(not, %[[D_BOOL]]) : !cir.bool, !cir.bool504// CHECK: cir.store{{.*}} %[[D_NOT]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>505 506// LLVM: define{{.*}} void @_Z16test_logical_notv()507// LLVM: %[[A:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4508// LLVM: %[[A_BOOL:.*]] = icmp ne i32 %[[A]], 0509// LLVM: %[[A_NOT:.*]] = xor i1 %[[A_BOOL]], true510// LLVM: %[[A_CAST:.*]] = zext i1 %[[A_NOT]] to i32511// LLVM: store i32 %[[A_CAST]], ptr %[[A_ADDR]], align 4512// LLVM: %[[B:.*]] = load i8, ptr %[[B_ADDR:.*]], align 1513// LLVM: %[[B_BOOL:.*]] = trunc i8 %[[B]] to i1514// LLVM: %[[B_NOT:.*]] = xor i1 %[[B_BOOL]], true515// LLVM: %[[B_CAST:.*]] = zext i1 %[[B_NOT]] to i8516// LLVM: store i8 %[[B_CAST]], ptr %[[B_ADDR]], align 1517// LLVM: %[[C:.*]] = load float, ptr %[[C_ADDR:.*]], align 4518// LLVM: %[[C_BOOL:.*]] = fcmp une float %[[C]], 0.000000e+00519// LLVM: %[[C_NOT:.*]] = xor i1 %[[C_BOOL]], true520// LLVM: %[[C_CAST:.*]] = uitofp i1 %[[C_NOT]] to float521// LLVM: store float %[[C_CAST]], ptr %[[C_ADDR]], align 4522// LLVM: %[[P:.*]] = load ptr, ptr %[[P_ADDR:.*]], align 8523// LLVM: %[[P_BOOL:.*]] = icmp ne ptr %[[P]], null524// LLVM: %[[P_NOT:.*]] = xor i1 %[[P_BOOL]], true525// LLVM: %[[P_CAST:.*]] = zext i1 %[[P_NOT]] to i8526// LLVM: store i8 %[[P_CAST]], ptr %[[B_ADDR]], align 1527// LLVM: %[[D:.*]] = load double, ptr %[[D_ADDR:.*]], align 8528// LLVM: %[[D_BOOL:.*]] = fcmp une double %[[D]], 0.000000e+00529// LLVM: %[[D_NOT:.*]] = xor i1 %[[D_BOOL]], true530// LLVM: %[[D_CAST:.*]] = zext i1 %[[D_NOT]] to i8531// LLVM: store i8 %[[D_CAST]], ptr %[[B_ADDR]], align 1532 533// OGCG: define{{.*}} void @_Z16test_logical_notv()534// OGCG: %[[A:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4535// OGCG: %[[A_BOOL:.*]] = icmp ne i32 %[[A]], 0536// OGCG: %[[A_NOT:.*]] = xor i1 %[[A_BOOL]], true537// OGCG: %[[A_CAST:.*]] = zext i1 %[[A_NOT]] to i32538// OGCG: store i32 %[[A_CAST]], ptr %[[A_ADDR]], align 4539// OGCG: %[[B:.*]] = load i8, ptr %[[B_ADDR:.*]], align 1540// OGCG: %[[B_BOOL:.*]] = trunc i8 %[[B]] to i1541// OGCG: %[[B_NOT:.*]] = xor i1 %[[B_BOOL]], true542// OGCG: %[[B_CAST:.*]] = zext i1 %[[B_NOT]] to i8543// OGCG: store i8 %[[B_CAST]], ptr %[[B_ADDR]], align 1544// OGCG: %[[C:.*]] = load float, ptr %[[C_ADDR:.*]], align 4545// OGCG: %[[C_BOOL:.*]] = fcmp une float %[[C]], 0.000000e+00546// OGCG: %[[C_NOT:.*]] = xor i1 %[[C_BOOL]], true547// OGCG: %[[C_CAST:.*]] = uitofp i1 %[[C_NOT]] to float548// OGCG: store float %[[C_CAST]], ptr %[[C_ADDR]], align 4549// OGCG: %[[P:.*]] = load ptr, ptr %[[P_ADDR:.*]], align 8550// OGCG: %[[P_BOOL:.*]] = icmp ne ptr %[[P]], null551// OGCG: %[[P_NOT:.*]] = xor i1 %[[P_BOOL]], true552// OGCG: %[[P_CAST:.*]] = zext i1 %[[P_NOT]] to i8553// OGCG: store i8 %[[P_CAST]], ptr %[[B_ADDR]], align 1554// OGCG: %[[D:.*]] = load double, ptr %[[D_ADDR:.*]], align 8555// OGCG: %[[D_BOOL:.*]] = fcmp une double %[[D]], 0.000000e+00556// OGCG: %[[D_NOT:.*]] = xor i1 %[[D_BOOL]], true557// OGCG: %[[D_CAST:.*]] = zext i1 %[[D_NOT]] to i8558// OGCG: store i8 %[[D_CAST]], ptr %[[B_ADDR]], align 1559 560void f16NestedUPlus() {561 _Float16 a;562 _Float16 b = +(+a);563}564 565// CHECK: cir.func{{.*}} @_Z14f16NestedUPlusv()566// CHECK: %[[A_ADDR:.*]] = cir.alloca !cir.f16, !cir.ptr<!cir.f16>, ["a"]567// CHECK: %[[B_ADDR:.*]] = cir.alloca !cir.f16, !cir.ptr<!cir.f16>, ["b", init]568// CHECK: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.f16>, !cir.f16569// CHECK: %[[A_F32:.*]] = cir.cast floating %[[TMP_A]] : !cir.f16 -> !cir.float570// CHECK: %[[A_PLUS:.*]] = cir.unary(plus, %[[A_F32]]) : !cir.float, !cir.float571// CHECK: %[[RESULT_F32:.*]] = cir.unary(plus, %[[A_PLUS]]) : !cir.float, !cir.float572// CHECK: %[[RESULT:.*]] = cir.cast floating %[[RESULT_F32]] : !cir.float -> !cir.f16573// CHECK: cir.store{{.*}} %[[RESULT]], %[[B_ADDR]] : !cir.f16, !cir.ptr<!cir.f16>574 575// LLVM: define{{.*}} void @_Z14f16NestedUPlusv()576// LLVM: %[[A_ADDR:.*]] = alloca half, i64 1, align 2577// LLVM: %[[B_ADDR:.*]] = alloca half, i64 1, align 2578// LLVM: %[[TMP_A:.*]] = load half, ptr %[[A_ADDR]], align 2579// LLVM: %[[RESULT_F32:.*]] = fpext half %[[TMP_A]] to float580// LLVM: %[[RESULT:.*]] = fptrunc float %[[RESULT_F32]] to half581// LLVM: store half %[[RESULT]], ptr %[[B_ADDR]], align 2582 583// OGCG: define{{.*}} void @_Z14f16NestedUPlusv()584// OGCG: %[[A_ADDR:.*]] = alloca half, align 2585// OGCG: %[[B_ADDR:.*]] = alloca half, align 2586// OGCG: %[[TMP_A:.*]] = load half, ptr %[[A_ADDR]], align 2587// OGCG: %[[RESULT_F32:.*]] = fpext half %[[TMP_A]] to float588// OGCG: %[[RESULT:.*]] = fptrunc float %[[RESULT_F32]] to half589// OGCG: store half %[[RESULT]], ptr %[[B_ADDR]], align 2590 591void f16NestedUMinus() {592 _Float16 a;593 _Float16 b = -(-a);594}595 596// CHECK: cir.func{{.*}} @_Z15f16NestedUMinusv()597// CHECK: %[[A_ADDR:.*]] = cir.alloca !cir.f16, !cir.ptr<!cir.f16>, ["a"]598// CHECK: %[[B_ADDR:.*]] = cir.alloca !cir.f16, !cir.ptr<!cir.f16>, ["b", init]599// CHECK: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.f16>, !cir.f16600// CHECK: %[[A_F32:.*]] = cir.cast floating %[[TMP_A]] : !cir.f16 -> !cir.float601// CHECK: %[[A_MINUS:.*]] = cir.unary(minus, %[[A_F32]]) : !cir.float, !cir.float602// CHECK: %[[RESULT_F32:.*]] = cir.unary(minus, %[[A_MINUS]]) : !cir.float, !cir.float603// CHECK: %[[RESULT:.*]] = cir.cast floating %[[RESULT_F32]] : !cir.float -> !cir.f16604// CHECK: cir.store{{.*}} %[[RESULT]], %[[B_ADDR]] : !cir.f16, !cir.ptr<!cir.f16>605 606// LLVM: define{{.*}} void @_Z15f16NestedUMinusv()607// LLVM: %[[A_ADDR:.*]] = alloca half, i64 1, align 2608// LLVM: %[[B_ADDR:.*]] = alloca half, i64 1, align 2609// LLVM: %[[TMP_A:.*]] = load half, ptr %[[A_ADDR]], align 2610// LLVM: %[[A_F32:.*]] = fpext half %[[TMP_A]] to float611// LLVM: %[[A_MINUS:.*]] = fneg float %[[A_F32]]612// LLVM: %[[RESULT_F32:.*]] = fneg float %[[A_MINUS]]613// LLVM: %[[RESULT:.*]] = fptrunc float %[[RESULT_F32]] to half614// LLVM: store half %[[RESULT]], ptr %[[B_ADDR]], align 2615 616// OGCG: define{{.*}} void @_Z15f16NestedUMinusv()617// OGCG: %[[A_ADDR:.*]] = alloca half, align 2618// OGCG: %[[B_ADDR:.*]] = alloca half, align 2619// OGCG: %[[TMP_A:.*]] = load half, ptr %[[A_ADDR]], align 2620// OGCG: %[[A_F32:.*]] = fpext half %[[TMP_A]] to float621// OGCG: %[[A_MINUS:.*]] = fneg float %[[A_F32]]622// OGCG: %[[RESULT_F32:.*]] = fneg float %[[A_MINUS]]623// OGCG: %[[RESULT:.*]] = fptrunc float %[[RESULT_F32]] to half624// OGCG: store half %[[RESULT]], ptr %[[B_ADDR]], align 2625