@@ -466,3 +466,93 @@ _Float16 fp16UMinus(_Float16 f) {
466
466
// OGCG: %[[PROMOTED:.*]] = fpext half %[[F_LOAD]] to float
467
467
// OGCG: %[[RESULT:.*]] = fneg float %[[PROMOTED]]
468
468
// OGCG: %[[UNPROMOTED:.*]] = fptrunc float %[[RESULT]] to half
469
+
470
+ void 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 @test_logical_not()
484
+ // CHECK: %[[A:.*]] = cir.load %[[A_ADDR:.*]] : !cir.ptr<!s32i>, !s32i
485
+ // CHECK: %[[A_BOOL:.*]] = cir.cast(int_to_bool, %[[A]] : !s32i), !cir.bool
486
+ // CHECK: %[[A_NOT:.*]] = cir.unary(not, %[[A_BOOL]]) : !cir.bool, !cir.bool
487
+ // CHECK: %[[A_CAST:.*]] = cir.cast(bool_to_int, %[[A_NOT]] : !cir.bool), !s32i
488
+ // CHECK: cir.store %[[A_CAST]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>
489
+ // CHECK: %[[B:.*]] = cir.load %[[B_ADDR:.*]] : !cir.ptr<!cir.bool>, !cir.bool
490
+ // CHECK: %[[B_NOT:.*]] = cir.unary(not, %[[B]]) : !cir.bool, !cir.bool
491
+ // 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.float
493
+ // CHECK: %[[C_BOOL:.*]] = cir.cast(float_to_bool, %[[C]] : !cir.float), !cir.bool
494
+ // CHECK: %[[C_NOT:.*]] = cir.unary(not, %[[C_BOOL]]) : !cir.bool, !cir.bool
495
+ // CHECK: %[[C_CAST:.*]] = cir.cast(bool_to_float, %[[C_NOT]] : !cir.bool), !cir.float
496
+ // 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.bool
499
+ // CHECK: %[[P_NOT:.*]] = cir.unary(not, %[[P_BOOL]]) : !cir.bool, !cir.bool
500
+ // 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.double
502
+ // CHECK: %[[D_BOOL:.*]] = cir.cast(float_to_bool, %[[D]] : !cir.double), !cir.bool
503
+ // CHECK: %[[D_NOT:.*]] = cir.unary(not, %[[D_BOOL]]) : !cir.bool, !cir.bool
504
+ // CHECK: cir.store %[[D_NOT]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>
505
+
506
+ // LLVM: define void @test_logical_not()
507
+ // LLVM: %[[A:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4
508
+ // LLVM: %[[A_BOOL:.*]] = icmp ne i32 %[[A]], 0
509
+ // LLVM: %[[A_NOT:.*]] = xor i1 %[[A_BOOL]], true
510
+ // LLVM: %[[A_CAST:.*]] = zext i1 %[[A_NOT]] to i32
511
+ // LLVM: store i32 %[[A_CAST]], ptr %[[A_ADDR]], align 4
512
+ // LLVM: %[[B:.*]] = load i8, ptr %[[B_ADDR:.*]], align 1
513
+ // LLVM: %[[B_BOOL:.*]] = trunc i8 %[[B]] to i1
514
+ // LLVM: %[[B_NOT:.*]] = xor i1 %[[B_BOOL]], true
515
+ // LLVM: %[[B_CAST:.*]] = zext i1 %[[B_NOT]] to i8
516
+ // LLVM: store i8 %[[B_CAST]], ptr %[[B_ADDR]], align 1
517
+ // LLVM: %[[C:.*]] = load float, ptr %[[C_ADDR:.*]], align 4
518
+ // LLVM: %[[C_BOOL:.*]] = fcmp une float %[[C]], 0.000000e+00
519
+ // LLVM: %[[C_NOT:.*]] = xor i1 %[[C_BOOL]], true
520
+ // LLVM: %[[C_CAST:.*]] = uitofp i1 %[[C_NOT]] to float
521
+ // LLVM: store float %[[C_CAST]], ptr %[[C_ADDR]], align 4
522
+ // LLVM: %[[P:.*]] = load ptr, ptr %[[P_ADDR:.*]], align 8
523
+ // LLVM: %[[P_BOOL:.*]] = icmp ne ptr %[[P]], null
524
+ // LLVM: %[[P_NOT:.*]] = xor i1 %[[P_BOOL]], true
525
+ // LLVM: %[[P_CAST:.*]] = zext i1 %[[P_NOT]] to i8
526
+ // LLVM: store i8 %[[P_CAST]], ptr %[[B_ADDR]], align 1
527
+ // LLVM: %[[D:.*]] = load double, ptr %[[D_ADDR:.*]], align 8
528
+ // LLVM: %[[D_BOOL:.*]] = fcmp une double %[[D]], 0.000000e+00
529
+ // LLVM: %[[D_NOT:.*]] = xor i1 %[[D_BOOL]], true
530
+ // LLVM: %[[D_CAST:.*]] = zext i1 %[[D_NOT]] to i8
531
+ // LLVM: store i8 %[[D_CAST]], ptr %[[B_ADDR]], align 1
532
+
533
+ // OGCG: define{{.*}} void @_Z16test_logical_notv()
534
+ // OGCG: %[[A:.*]] = load i32, ptr %[[A_ADDR:.*]], align 4
535
+ // OGCG: %[[A_BOOL:.*]] = icmp ne i32 %[[A]], 0
536
+ // OGCG: %[[A_NOT:.*]] = xor i1 %[[A_BOOL]], true
537
+ // OGCG: %[[A_CAST:.*]] = zext i1 %[[A_NOT]] to i32
538
+ // OGCG: store i32 %[[A_CAST]], ptr %[[A_ADDR]], align 4
539
+ // OGCG: %[[B:.*]] = load i8, ptr %[[B_ADDR:.*]], align 1
540
+ // OGCG: %[[B_BOOL:.*]] = trunc i8 %[[B]] to i1
541
+ // OGCG: %[[B_NOT:.*]] = xor i1 %[[B_BOOL]], true
542
+ // OGCG: %[[B_CAST:.*]] = zext i1 %[[B_NOT]] to i8
543
+ // OGCG: store i8 %[[B_CAST]], ptr %[[B_ADDR]], align 1
544
+ // OGCG: %[[C:.*]] = load float, ptr %[[C_ADDR:.*]], align 4
545
+ // OGCG: %[[C_BOOL:.*]] = fcmp une float %[[C]], 0.000000e+00
546
+ // OGCG: %[[C_NOT:.*]] = xor i1 %[[C_BOOL]], true
547
+ // OGCG: %[[C_CAST:.*]] = uitofp i1 %[[C_NOT]] to float
548
+ // OGCG: store float %[[C_CAST]], ptr %[[C_ADDR]], align 4
549
+ // OGCG: %[[P:.*]] = load ptr, ptr %[[P_ADDR:.*]], align 8
550
+ // OGCG: %[[P_BOOL:.*]] = icmp ne ptr %[[P]], null
551
+ // OGCG: %[[P_NOT:.*]] = xor i1 %[[P_BOOL]], true
552
+ // OGCG: %[[P_CAST:.*]] = zext i1 %[[P_NOT]] to i8
553
+ // OGCG: store i8 %[[P_CAST]], ptr %[[B_ADDR]], align 1
554
+ // OGCG: %[[D:.*]] = load double, ptr %[[D_ADDR:.*]], align 8
555
+ // OGCG: %[[D_BOOL:.*]] = fcmp une double %[[D]], 0.000000e+00
556
+ // OGCG: %[[D_NOT:.*]] = xor i1 %[[D_BOOL]], true
557
+ // OGCG: %[[D_CAST:.*]] = zext i1 %[[D_NOT]] to i8
558
+ // OGCG: store i8 %[[D_CAST]], ptr %[[B_ADDR]], align 1
0 commit comments