1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt < %s -S -passes=instcombine | FileCheck %s 3 4declare void @use(i1) 5 6define i1 @a_or_b(i32 %a, i32 %b) { 7; CHECK-LABEL: define i1 @a_or_b( 8; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 9; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A]], 0 10; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[B]], 0 11; CHECK-NEXT: [[OR:%.*]] = xor i1 [[TMP1]], [[TMP2]] 12; CHECK-NEXT: ret i1 [[OR]] 13; 14 %a_eq_zero = icmp eq i32 %a, 0 15 %b_ne_zero = icmp ne i32 %b, 0 16 %and.1 = and i1 %a_eq_zero, %b_ne_zero 17 %a_ne_zero = icmp ne i32 %a, 0 18 %b_eq_zero = icmp eq i32 %b, 0 19 %and.2 = and i1 %a_ne_zero, %b_eq_zero 20 %or = or i1 %and.1, %and.2 21 ret i1 %or 22} 23 24define i1 @a_or_b_not_inv(i32 %a, i32 %b){ 25; CHECK-LABEL: define i1 @a_or_b_not_inv( 26; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 27; CHECK-NEXT: [[A_EQ_ZERO:%.*]] = icmp eq i32 [[A]], 0 28; CHECK-NEXT: [[B_NE_ZERO:%.*]] = icmp ne i32 [[B]], 0 29; CHECK-NEXT: [[AND_1:%.*]] = and i1 [[A_EQ_ZERO]], [[B_NE_ZERO]] 30; CHECK-NEXT: [[A_NE_ZERO:%.*]] = icmp ne i32 [[A]], 0 31; CHECK-NEXT: [[B_EQ_1:%.*]] = icmp eq i32 [[B]], 1 32; CHECK-NEXT: [[AND_2:%.*]] = and i1 [[A_NE_ZERO]], [[B_EQ_1]] 33; CHECK-NEXT: [[OR:%.*]] = or i1 [[AND_1]], [[AND_2]] 34; CHECK-NEXT: ret i1 [[OR]] 35; 36 %a_eq_zero = icmp eq i32 %a, 0 37 %b_ne_zero = icmp ne i32 %b, 0 38 %and.1 = and i1 %a_eq_zero, %b_ne_zero 39 %a_ne_zero = icmp ne i32 %a, 0 40 %b_eq_1 = icmp eq i32 %b, 1 41 %and.2 = and i1 %a_ne_zero, %b_eq_1 42 %or = or i1 %and.1, %and.2 43 ret i1 %or 44} 45 46define i1 @a_or_b_const(i32 %a, i32 %b, i32 %c) { 47; CHECK-LABEL: define i1 @a_or_b_const( 48; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 49; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A]], [[C]] 50; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[B]], [[C]] 51; CHECK-NEXT: [[OR:%.*]] = xor i1 [[TMP1]], [[TMP2]] 52; CHECK-NEXT: ret i1 [[OR]] 53; 54 %a_eq_c = icmp eq i32 %a, %c 55 %b_ne_c = icmp ne i32 %b, %c 56 %and.1 = and i1 %a_eq_c, %b_ne_c 57 %a_ne_c = icmp ne i32 %a, %c 58 %b_eq_c = icmp eq i32 %b, %c 59 %and.2 = and i1 %a_ne_c, %b_eq_c 60 %or = or i1 %and.1, %and.2 61 ret i1 %or 62} 63 64define i1 @a_or_b_const2(i32 %a, i32 %b, i32 %c, i32 %d) { 65; CHECK-LABEL: define i1 @a_or_b_const2( 66; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 67; CHECK-NEXT: [[A_EQ_C:%.*]] = icmp eq i32 [[A]], [[C]] 68; CHECK-NEXT: [[B_EQ_D:%.*]] = icmp eq i32 [[B]], [[D]] 69; CHECK-NEXT: [[OR:%.*]] = xor i1 [[A_EQ_C]], [[B_EQ_D]] 70; CHECK-NEXT: ret i1 [[OR]] 71; 72 %a_eq_c = icmp eq i32 %a, %c 73 %b_ne_d = icmp ne i32 %b, %d 74 %and.1 = and i1 %a_eq_c, %b_ne_d 75 %a_ne_c = icmp ne i32 %a, %c 76 %b_eq_d = icmp eq i32 %b, %d 77 %and.2 = and i1 %a_ne_c, %b_eq_d 78 %or = or i1 %and.1, %and.2 79 ret i1 %or 80} 81define i1 @a_or_b_nullptr(ptr %a, ptr %b) { 82; CHECK-LABEL: define i1 @a_or_b_nullptr( 83; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) { 84; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[A]], null 85; CHECK-NEXT: [[TMP2:%.*]] = icmp eq ptr [[B]], null 86; CHECK-NEXT: [[OR:%.*]] = xor i1 [[TMP1]], [[TMP2]] 87; CHECK-NEXT: ret i1 [[OR]] 88; 89 %a_null = icmp eq ptr %a, null 90 %b_null = icmp eq ptr %b, null 91 %a_not_null = icmp ne ptr %a, null 92 %b_not_null = icmp ne ptr %b, null 93 %and.1 = and i1 %a_null, %b_not_null 94 %and.2 = and i1 %a_not_null, %b_null 95 %or = or i1 %and.1, %and.2 96 ret i1 %or 97} 98 99define i1 @a_or_b_multiple_uses(i32 %a, i32 %b) { 100; CHECK-LABEL: define i1 @a_or_b_multiple_uses( 101; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 102; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A]], 0 103; CHECK-NEXT: [[A_NE_ZERO:%.*]] = icmp ne i32 [[A]], 0 104; CHECK-NEXT: [[B_EQ_ZERO:%.*]] = icmp eq i32 [[B]], 0 105; CHECK-NEXT: [[AND_2:%.*]] = and i1 [[A_NE_ZERO]], [[B_EQ_ZERO]] 106; CHECK-NEXT: call void @use(i1 [[AND_2]]) 107; CHECK-NEXT: [[OR:%.*]] = xor i1 [[TMP1]], [[B_EQ_ZERO]] 108; CHECK-NEXT: ret i1 [[OR]] 109; 110 %a_eq_zero = icmp eq i32 %a, 0 111 %b_ne_zero = icmp ne i32 %b, 0 112 %and.1 = and i1 %a_eq_zero, %b_ne_zero 113 %a_ne_zero = icmp ne i32 %a, 0 114 %b_eq_zero = icmp eq i32 %b, 0 115 %and.2 = and i1 %a_ne_zero, %b_eq_zero 116 call void @use(i1 %and.2) 117 %or = or i1 %and.1, %and.2 118 ret i1 %or 119} 120 121define i1 @a_or_b_multiple_uses_2(i32 %a, i32 %b) { 122; CHECK-LABEL: define i1 @a_or_b_multiple_uses_2( 123; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 124; CHECK-NEXT: [[A_EQ_ZERO:%.*]] = icmp eq i32 [[A]], 0 125; CHECK-NEXT: [[B_NE_ZERO:%.*]] = icmp ne i32 [[B]], 0 126; CHECK-NEXT: call void @use(i1 [[B_NE_ZERO]]) 127; CHECK-NEXT: [[AND_1:%.*]] = and i1 [[A_EQ_ZERO]], [[B_NE_ZERO]] 128; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[B]], 0 129; CHECK-NEXT: call void @use(i1 [[AND_1]]) 130; CHECK-NEXT: [[OR:%.*]] = xor i1 [[A_EQ_ZERO]], [[TMP1]] 131; CHECK-NEXT: ret i1 [[OR]] 132; 133 %a_eq_zero = icmp eq i32 %a, 0 134 %b_ne_zero = icmp ne i32 %b, 0 135 call void @use(i1 %b_ne_zero) 136 %and.1 = and i1 %a_eq_zero, %b_ne_zero 137 %a_ne_zero = icmp ne i32 %a, 0 138 %b_eq_zero = icmp eq i32 %b, 0 139 %and.2 = and i1 %a_ne_zero, %b_eq_zero 140 call void @use(i1 %and.1) 141 %or = or i1 %and.1, %and.2 142 ret i1 %or 143} 144 145 146