1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define i1 @eq_zero(i4 %x, i4 %y) { 5; CHECK-LABEL: @eq_zero( 6; CHECK-NEXT: [[I0:%.*]] = icmp eq i4 [[X:%.*]], 0 7; CHECK-NEXT: [[I1:%.*]] = icmp eq i4 [[Y:%.*]], 0 8; CHECK-NEXT: [[R:%.*]] = xor i1 [[I0]], [[I1]] 9; CHECK-NEXT: ret i1 [[R]] 10; 11 %i0 = icmp eq i4 %x, 0 12 %i1 = icmp eq i4 %y, 0 13 %r = xor i1 %i0, %i1 14 ret i1 %r 15} 16 17define i1 @ne_zero(i4 %x, i4 %y) { 18; CHECK-LABEL: @ne_zero( 19; CHECK-NEXT: [[I0:%.*]] = icmp ne i4 [[X:%.*]], 0 20; CHECK-NEXT: [[I1:%.*]] = icmp ne i4 [[Y:%.*]], 0 21; CHECK-NEXT: [[R:%.*]] = xor i1 [[I0]], [[I1]] 22; CHECK-NEXT: ret i1 [[R]] 23; 24 %i0 = icmp ne i4 %x, 0 25 %i1 = icmp ne i4 %y, 0 26 %r = xor i1 %i0, %i1 27 ret i1 %r 28} 29 30define i1 @eq_ne_zero(i4 %x, i4 %y) { 31; CHECK-LABEL: @eq_ne_zero( 32; CHECK-NEXT: [[I0:%.*]] = icmp eq i4 [[X:%.*]], 0 33; CHECK-NEXT: [[I1:%.*]] = icmp ne i4 [[Y:%.*]], 0 34; CHECK-NEXT: [[R:%.*]] = xor i1 [[I0]], [[I1]] 35; CHECK-NEXT: ret i1 [[R]] 36; 37 %i0 = icmp eq i4 %x, 0 38 %i1 = icmp ne i4 %y, 0 39 %r = xor i1 %i0, %i1 40 ret i1 %r 41} 42 43define i1 @slt_zero(i4 %x, i4 %y) { 44; CHECK-LABEL: @slt_zero( 45; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]] 46; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i4 [[TMP1]], 0 47; CHECK-NEXT: ret i1 [[TMP2]] 48; 49 %i0 = icmp slt i4 %x, 0 50 %i1 = icmp slt i4 %y, 0 51 %r = xor i1 %i0, %i1 52 ret i1 %r 53} 54 55; Don't increase the instruction count. 56 57declare void @use(i1) 58 59define i1 @slt_zero_extra_uses(i4 %x, i4 %y) { 60; CHECK-LABEL: @slt_zero_extra_uses( 61; CHECK-NEXT: [[I0:%.*]] = icmp slt i4 [[X:%.*]], 0 62; CHECK-NEXT: [[I1:%.*]] = icmp slt i4 [[Y:%.*]], 0 63; CHECK-NEXT: [[R:%.*]] = xor i1 [[I0]], [[I1]] 64; CHECK-NEXT: call void @use(i1 [[I0]]) 65; CHECK-NEXT: call void @use(i1 [[I1]]) 66; CHECK-NEXT: ret i1 [[R]] 67; 68 %i0 = icmp slt i4 %x, 0 69 %i1 = icmp slt i4 %y, 0 70 %r = xor i1 %i0, %i1 71 call void @use(i1 %i0) 72 call void @use(i1 %i1) 73 ret i1 %r 74} 75 76define i1 @sgt_zero(i4 %x, i4 %y) { 77; CHECK-LABEL: @sgt_zero( 78; CHECK-NEXT: [[I0:%.*]] = icmp sgt i4 [[X:%.*]], 0 79; CHECK-NEXT: [[I1:%.*]] = icmp sgt i4 [[Y:%.*]], 0 80; CHECK-NEXT: [[R:%.*]] = xor i1 [[I0]], [[I1]] 81; CHECK-NEXT: ret i1 [[R]] 82; 83 %i0 = icmp sgt i4 %x, 0 84 %i1 = icmp sgt i4 %y, 0 85 %r = xor i1 %i0, %i1 86 ret i1 %r 87} 88 89define i1 @sgt_minus1(i4 %x, i4 %y) { 90; CHECK-LABEL: @sgt_minus1( 91; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]] 92; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i4 [[TMP1]], 0 93; CHECK-NEXT: ret i1 [[TMP2]] 94; 95 %i0 = icmp sgt i4 %x, -1 96 %i1 = icmp sgt i4 %y, -1 97 %r = xor i1 %i0, %i1 98 ret i1 %r 99} 100 101define i1 @slt_zero_sgt_minus1(i4 %x, i4 %y) { 102; CHECK-LABEL: @slt_zero_sgt_minus1( 103; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]] 104; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i4 [[TMP1]], -1 105; CHECK-NEXT: ret i1 [[TMP2]] 106; 107 %i0 = icmp slt i4 %x, 0 108 %i1 = icmp sgt i4 %y, -1 109 %r = xor i1 %i0, %i1 110 ret i1 %r 111} 112 113define <2 x i1> @sgt_minus1_slt_zero_sgt(<2 x i4> %x, <2 x i4> %y) { 114; CHECK-LABEL: @sgt_minus1_slt_zero_sgt( 115; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]] 116; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <2 x i4> [[TMP1]], <i4 -1, i4 -1> 117; CHECK-NEXT: ret <2 x i1> [[TMP2]] 118; 119 %i1 = icmp sgt <2 x i4> %x, <i4 -1, i4 -1> 120 %i0 = icmp slt <2 x i4> %y, zeroinitializer 121 %r = xor <2 x i1> %i0, %i1 122 ret <2 x i1> %r 123} 124 125; Don't try (crash) if the operand types don't match. 126 127define i1 @different_type_cmp_ops(i32 %x, i64 %y) { 128; CHECK-LABEL: @different_type_cmp_ops( 129; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 0 130; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[Y:%.*]], 0 131; CHECK-NEXT: [[R:%.*]] = xor i1 [[CMP1]], [[CMP2]] 132; CHECK-NEXT: ret i1 [[R]] 133; 134 %cmp1 = icmp slt i32 %x, 0 135 %cmp2 = icmp slt i64 %y, 0 136 %r = xor i1 %cmp1, %cmp2 137 ret i1 %r 138} 139 140define i1 @test13(i8 %A, i8 %B) { 141; CHECK-LABEL: @test13( 142; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[A:%.*]], [[B:%.*]] 143; CHECK-NEXT: ret i1 [[TMP1]] 144; 145 %C = icmp ult i8 %A, %B 146 %D = icmp ugt i8 %A, %B 147 %E = xor i1 %C, %D 148 ret i1 %E 149} 150 151define i1 @test14(i8 %A, i8 %B) { 152; CHECK-LABEL: @test14( 153; CHECK-NEXT: ret i1 true 154; 155 %C = icmp eq i8 %A, %B 156 %D = icmp ne i8 %B, %A 157 %E = xor i1 %C, %D 158 ret i1 %E 159} 160 161define i1 @xor_icmp_ptr(i8* %c, i8* %d) { 162; CHECK-LABEL: @xor_icmp_ptr( 163; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8* [[C:%.*]], null 164; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8* [[D:%.*]], null 165; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP]], [[CMP1]] 166; CHECK-NEXT: ret i1 [[XOR]] 167; 168 %cmp = icmp slt i8* %c, null 169 %cmp1 = icmp slt i8* %d, null 170 %xor = xor i1 %cmp, %cmp1 171 ret i1 %xor 172} 173 174