@@ -405,3 +405,93 @@ float fpPostInc2() {
405
405
// OGCG: store float %[[A_INC]], ptr %[[A]], align 4
406
406
// OGCG: store float %[[A_LOAD]], ptr %[[B]], align 4
407
407
// OGCG: %[[B_TO_OUTPUT:.*]] = load float, ptr %[[B]], align 4
408
+
409
+ void test_logical_not () {
410
+ int a = 5 ;
411
+ a = !a;
412
+ bool b = false ;
413
+ b = !b;
414
+ float c = 2 .0f ;
415
+ c = !c;
416
+ int *p = 0 ;
417
+ b = !p;
418
+ double d = 3.0 ;
419
+ b = !d;
420
+ }
421
+
422
+ // CHECK: cir.func @test_logical_not()
423
+ // CHECK: %[[A:.*]] = cir.load %[[A_ADDR:.*]] : !cir.ptr<!s32i>, !s32i
424
+ // CHECK: %[[A_BOOL:.*]] = cir.cast(int_to_bool, %[[A]] : !s32i), !cir.bool
425
+ // CHECK: %[[A_NOT:.*]] = cir.unary(not, %[[A_BOOL]]) : !cir.bool, !cir.bool
426
+ // CHECK: %[[A_CAST:.*]] = cir.cast(bool_to_int, %[[A_NOT]] : !cir.bool), !s32i
427
+ // CHECK: cir.store %[[A_CAST]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>
428
+ // CHECK: %[[B:.*]] = cir.load %[[B_ADDR:.*]] : !cir.ptr<!cir.bool>, !cir.bool
429
+ // CHECK: %[[B_NOT:.*]] = cir.unary(not, %[[B]]) : !cir.bool, !cir.bool
430
+ // CHECK: cir.store %[[B_NOT]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>
431
+ // CHECK: %[[C:.*]] = cir.load %[[C_ADDR:.*]] : !cir.ptr<!cir.float>, !cir.float
432
+ // CHECK: %[[C_BOOL:.*]] = cir.cast(float_to_bool, %[[C]] : !cir.float), !cir.bool
433
+ // CHECK: %[[C_NOT:.*]] = cir.unary(not, %[[C_BOOL]]) : !cir.bool, !cir.bool
434
+ // CHECK: %[[C_CAST:.*]] = cir.cast(bool_to_float, %[[C_NOT]] : !cir.bool), !cir.float
435
+ // CHECK: cir.store %[[C_CAST]], %[[C_ADDR]] : !cir.float, !cir.ptr<!cir.float>
436
+ // CHECK: %[[P:.*]] = cir.load %[[P_ADDR:.*]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
437
+ // CHECK: %[[P_BOOL:.*]] = cir.cast(ptr_to_bool, %[[P]] : !cir.ptr<!s32i>), !cir.bool
438
+ // CHECK: %[[P_NOT:.*]] = cir.unary(not, %[[P_BOOL]]) : !cir.bool, !cir.bool
439
+ // CHECK: cir.store %[[P_NOT]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>
440
+ // CHECK: %[[D:.*]] = cir.load %[[D_ADDR:.*]] : !cir.ptr<!cir.double>, !cir.double
441
+ // CHECK: %[[D_BOOL:.*]] = cir.cast(float_to_bool, %[[D]] : !cir.double), !cir.bool
442
+ // CHECK: %[[D_NOT:.*]] = cir.unary(not, %[[D_BOOL]]) : !cir.bool, !cir.bool
443
+ // CHECK: cir.store %[[D_NOT]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>
444
+
445
+ // LLVM: define void @test_logical_not()
446
+ // LLVM: %[[A:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4
447
+ // LLVM: %[[A_BOOL:.*]] = icmp ne i32 %[[A]], 0
448
+ // LLVM: %[[A_NOT:.*]] = xor i1 %[[A_BOOL]], true
449
+ // LLVM: %[[A_CAST:.*]] = zext i1 %[[A_NOT]] to i32
450
+ // LLVM: store i32 %[[A_CAST]], ptr %[[A_ADDR]], align 4
451
+ // LLVM: %[[B:.*]] = load i8, ptr %[[B_ADDR:.*]], align 1
452
+ // LLVM: %[[B_BOOL:.*]] = trunc i8 %[[B]] to i1
453
+ // LLVM: %[[B_NOT:.*]] = xor i1 %[[B_BOOL]], true
454
+ // LLVM: %[[B_CAST:.*]] = zext i1 %[[B_NOT]] to i8
455
+ // LLVM: store i8 %[[B_CAST]], ptr %[[B_ADDR]], align 1
456
+ // LLVM: %[[C:.*]] = load float, ptr %[[C_ADDR:.*]], align 4
457
+ // LLVM: %[[C_BOOL:.*]] = fcmp une float %[[C]], 0.000000e+00
458
+ // LLVM: %[[C_NOT:.*]] = xor i1 %[[C_BOOL]], true
459
+ // LLVM: %[[C_CAST:.*]] = uitofp i1 %[[C_NOT]] to float
460
+ // LLVM: store float %[[C_CAST]], ptr %[[C_ADDR]], align 4
461
+ // LLVM: %[[P:.*]] = load ptr, ptr %[[P_ADDR:.*]], align 8
462
+ // LLVM: %[[P_BOOL:.*]] = icmp ne ptr %[[P]], null
463
+ // LLVM: %[[P_NOT:.*]] = xor i1 %[[P_BOOL]], true
464
+ // LLVM: %[[P_CAST:.*]] = zext i1 %[[P_NOT]] to i8
465
+ // LLVM: store i8 %[[P_CAST]], ptr %[[B_ADDR]], align 1
466
+ // LLVM: %[[D:.*]] = load double, ptr %[[D_ADDR:.*]], align 8
467
+ // LLVM: %[[D_BOOL:.*]] = fcmp une double %[[D]], 0.000000e+00
468
+ // LLVM: %[[D_NOT:.*]] = xor i1 %[[D_BOOL]], true
469
+ // LLVM: %[[D_CAST:.*]] = zext i1 %[[D_NOT]] to i8
470
+ // LLVM: store i8 %[[D_CAST]], ptr %[[B_ADDR]], align 1
471
+
472
+ // OGCG: define{{.*}} void @_Z16test_logical_notv()
473
+ // OGCG: %[[A:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4
474
+ // OGCG: %[[A_BOOL:.*]] = icmp ne i32 %[[A]], 0
475
+ // OGCG: %[[A_NOT:.*]] = xor i1 %[[A_BOOL]], true
476
+ // OGCG: %[[A_CAST:.*]] = zext i1 %[[A_NOT]] to i32
477
+ // OGCG: store i32 %[[A_CAST]], ptr %[[A_ADDR]], align 4
478
+ // OGCG: %[[B:.*]] = load i8, ptr %[[B_ADDR:.*]], align 1
479
+ // OGCG: %[[B_BOOL:.*]] = trunc i8 %[[B]] to i1
480
+ // OGCG: %[[B_NOT:.*]] = xor i1 %[[B_BOOL]], true
481
+ // OGCG: %[[B_CAST:.*]] = zext i1 %[[B_NOT]] to i8
482
+ // OGCG: store i8 %[[B_CAST]], ptr %[[B_ADDR]], align 1
483
+ // OGCG: %[[C:.*]] = load float, ptr %[[C_ADDR:.*]], align 4
484
+ // OGCG: %[[C_BOOL:.*]] = fcmp une float %[[C]], 0.000000e+00
485
+ // OGCG: %[[C_NOT:.*]] = xor i1 %[[C_BOOL]], true
486
+ // OGCG: %[[C_CAST:.*]] = uitofp i1 %[[C_NOT]] to float
487
+ // OGCG: store float %[[C_CAST]], ptr %[[C_ADDR]], align 4
488
+ // OGCG: %[[P:.*]] = load ptr, ptr %[[P_ADDR:.*]], align 8
489
+ // OGCG: %[[P_BOOL:.*]] = icmp ne ptr %[[P]], null
490
+ // OGCG: %[[P_NOT:.*]] = xor i1 %[[P_BOOL]], true
491
+ // OGCG: %[[P_CAST:.*]] = zext i1 %[[P_NOT]] to i8
492
+ // OGCG: store i8 %[[P_CAST]], ptr %[[B_ADDR]], align 1
493
+ // OGCG: %[[D:.*]] = load double, ptr %[[D_ADDR:.*]], align 8
494
+ // OGCG: %[[D_BOOL:.*]] = fcmp une double %[[D]], 0.000000e+00
495
+ // OGCG: %[[D_NOT:.*]] = xor i1 %[[D_BOOL]], true
496
+ // OGCG: %[[D_CAST:.*]] = zext i1 %[[D_NOT]] to i8
497
+ // OGCG: store i8 %[[D_CAST]], ptr %[[B_ADDR]], align 1
0 commit comments