@@ -405,3 +405,93 @@ float fpPostInc2() {
405405// OGCG: store float %[[A_INC]], ptr %[[A]], align 4
406406// OGCG: store float %[[A_LOAD]], ptr %[[B]], align 4
407407// 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