1; RUN: opt < %s -instcombine -S | FileCheck %s 2 3define i32 @test1(i32 %A) { 4; CHECK-LABEL: @test1( 5; CHECK-NEXT: ret i32 %A 6; 7 %B = xor i32 %A, -1 8 %C = xor i32 %B, -1 9 ret i32 %C 10} 11 12define i1 @invert_icmp(i32 %A, i32 %B) { 13; CHECK-LABEL: @invert_icmp( 14; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 %A, %B 15; CHECK-NEXT: ret i1 [[CMP]] 16; 17 %cmp = icmp sle i32 %A, %B 18 %not = xor i1 %cmp, true 19 ret i1 %not 20} 21 22; PR1570 23 24define i1 @invert_fcmp(float %X, float %Y) { 25; CHECK-LABEL: @invert_fcmp( 26; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float %X, %Y 27; CHECK-NEXT: ret i1 [[CMP]] 28; 29 %cmp = fcmp olt float %X, %Y 30 %not = xor i1 %cmp, true 31 ret i1 %not 32} 33 34; PR2298 35 36define i1 @not_not_cmp(i32 %a, i32 %b) { 37; CHECK-LABEL: @not_not_cmp( 38; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 %b, %a 39; CHECK-NEXT: ret i1 [[CMP]] 40; 41 %nota = xor i32 %a, -1 42 %notb = xor i32 %b, -1 43 %cmp = icmp slt i32 %nota, %notb 44 ret i1 %cmp 45} 46 47define <2 x i1> @not_not_cmp_vector(<2 x i32> %a, <2 x i32> %b) { 48; CHECK-LABEL: @not_not_cmp_vector( 49; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> %b, %a 50; CHECK-NEXT: ret <2 x i1> [[CMP]] 51; 52 %nota = xor <2 x i32> %a, <i32 -1, i32 -1> 53 %notb = xor <2 x i32> %b, <i32 -1, i32 -1> 54 %cmp = icmp ugt <2 x i32> %nota, %notb 55 ret <2 x i1> %cmp 56} 57 58define i1 @not_cmp_constant(i32 %a) { 59; CHECK-LABEL: @not_cmp_constant( 60; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 %a, -43 61; CHECK-NEXT: ret i1 [[CMP]] 62; 63 %nota = xor i32 %a, -1 64 %cmp = icmp ugt i32 %nota, 42 65 ret i1 %cmp 66} 67 68define <2 x i1> @not_cmp_constant_vector(<2 x i32> %a) { 69; CHECK-LABEL: @not_cmp_constant_vector( 70; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> %a, <i32 -43, i32 -43> 71; CHECK-NEXT: ret <2 x i1> [[CMP]] 72; 73 %nota = xor <2 x i32> %a, <i32 -1, i32 -1> 74 %cmp = icmp slt <2 x i32> %nota, <i32 42, i32 42> 75 ret <2 x i1> %cmp 76} 77 78define <2 x i1> @test7(<2 x i32> %A, <2 x i32> %B) { 79; CHECK-LABEL: @test7( 80; CHECK-NEXT: [[COND:%.*]] = icmp sgt <2 x i32> %A, %B 81; CHECK-NEXT: ret <2 x i1> [[COND]] 82; 83 %cond = icmp sle <2 x i32> %A, %B 84 %Ret = xor <2 x i1> %cond, <i1 true, i1 true> 85 ret <2 x i1> %Ret 86} 87 88define i32 @not_ashr_not(i32 %A, i32 %B) { 89; CHECK-LABEL: @not_ashr_not( 90; CHECK-NEXT: [[NOT2:%.*]] = ashr i32 %A, %B 91; CHECK-NEXT: ret i32 [[NOT2]] 92; 93 %not1 = xor i32 %A, -1 94 %ashr = ashr i32 %not1, %B 95 %not2 = xor i32 %ashr, -1 96 ret i32 %not2 97} 98 99define i8 @not_ashr_const(i8 %x) { 100; CHECK-LABEL: @not_ashr_const( 101; CHECK-NEXT: [[NOT:%.*]] = lshr i8 41, %x 102; CHECK-NEXT: ret i8 [[NOT]] 103; 104 %shr = ashr i8 -42, %x 105 %not = xor i8 %shr, -1 106 ret i8 %not 107} 108 109define <2 x i8> @not_ashr_const_splat(<2 x i8> %x) { 110; CHECK-LABEL: @not_ashr_const_splat( 111; CHECK-NEXT: [[NOT:%.*]] = lshr <2 x i8> <i8 41, i8 41>, %x 112; CHECK-NEXT: ret <2 x i8> [[NOT]] 113; 114 %shr = ashr <2 x i8> <i8 -42, i8 -42>, %x 115 %not = xor <2 x i8> %shr, <i8 -1, i8 -1> 116 ret <2 x i8> %not 117} 118 119; We can't get rid of the 'not' on a logical shift of a negative constant. 120 121define i8 @not_lshr_const_negative(i8 %x) { 122; CHECK-LABEL: @not_lshr_const_negative( 123; CHECK-NEXT: [[SHR:%.*]] = lshr i8 -42, %x 124; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[SHR]], -1 125; CHECK-NEXT: ret i8 [[NOT]] 126; 127 %shr = lshr i8 -42, %x 128 %not = xor i8 %shr, -1 129 ret i8 %not 130} 131 132define i8 @not_lshr_const(i8 %x) { 133; CHECK-LABEL: @not_lshr_const( 134; CHECK-NEXT: [[NOT:%.*]] = ashr i8 -43, %x 135; CHECK-NEXT: ret i8 [[NOT]] 136; 137 %shr = lshr i8 42, %x 138 %not = xor i8 %shr, -1 139 ret i8 %not 140} 141 142define <2 x i8> @not_lshr_const_splat(<2 x i8> %x) { 143; CHECK-LABEL: @not_lshr_const_splat( 144; CHECK-NEXT: [[NOT:%.*]] = ashr <2 x i8> <i8 -43, i8 -43>, %x 145; CHECK-NEXT: ret <2 x i8> [[NOT]] 146; 147 %shr = lshr <2 x i8> <i8 42, i8 42>, %x 148 %not = xor <2 x i8> %shr, <i8 -1, i8 -1> 149 ret <2 x i8> %not 150} 151 152