brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.5 KiB · ac1ae34 Raw
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