1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5target triple = "x86_64-unknown-linux-gnu" 6 7declare void @use.i8(i8) 8 9; Should be optimized to one and. 10define i1 @test1(i32 %a, i32 %b) { 11; CHECK-LABEL: @test1( 12; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 13; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 65280 14; CHECK-NEXT: [[TMP:%.*]] = icmp ne i32 [[TMP2]], 0 15; CHECK-NEXT: ret i1 [[TMP]] 16; 17 %tmp1 = and i32 %a, 65280 18 %tmp3 = and i32 %b, 65280 19 %tmp = icmp ne i32 %tmp1, %tmp3 20 ret i1 %tmp 21} 22 23define <2 x i1> @test1vec(<2 x i32> %a, <2 x i32> %b) { 24; CHECK-LABEL: @test1vec( 25; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[A:%.*]], [[B:%.*]] 26; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], splat (i32 65280) 27; CHECK-NEXT: [[TMP:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer 28; CHECK-NEXT: ret <2 x i1> [[TMP]] 29; 30 %tmp1 = and <2 x i32> %a, <i32 65280, i32 65280> 31 %tmp3 = and <2 x i32> %b, <i32 65280, i32 65280> 32 %tmp = icmp ne <2 x i32> %tmp1, %tmp3 33 ret <2 x i1> %tmp 34} 35 36define i1 @test2(i64 %A) { 37; CHECK-LABEL: @test2( 38; CHECK-NEXT: [[AND:%.*]] = and i64 [[A:%.*]], 128 39; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[AND]], 0 40; CHECK-NEXT: ret i1 [[CMP]] 41; 42 %and = and i64 %A, 128 43 %cmp = icmp eq i64 %and, 0 44 ret i1 %cmp 45} 46 47define <2 x i1> @test2vec(<2 x i64> %A) { 48; CHECK-LABEL: @test2vec( 49; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> [[A:%.*]], splat (i64 128) 50; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i64> [[AND]], zeroinitializer 51; CHECK-NEXT: ret <2 x i1> [[CMP]] 52; 53 %and = and <2 x i64> %A, <i64 128, i64 128> 54 %cmp = icmp eq <2 x i64> %and, zeroinitializer 55 ret <2 x i1> %cmp 56} 57 58define i1 @test3(i64 %A) { 59; CHECK-LABEL: @test3( 60; CHECK-NEXT: [[AND:%.*]] = and i64 [[A:%.*]], 128 61; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[AND]], 0 62; CHECK-NEXT: ret i1 [[CMP]] 63; 64 %and = and i64 %A, 128 65 %cmp = icmp ne i64 %and, 0 66 ret i1 %cmp 67} 68 69define <2 x i1> @test3vec(<2 x i64> %A) { 70; CHECK-LABEL: @test3vec( 71; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> [[A:%.*]], splat (i64 128) 72; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i64> [[AND]], zeroinitializer 73; CHECK-NEXT: ret <2 x i1> [[CMP]] 74; 75 %and = and <2 x i64> %A, <i64 128, i64 128> 76 %cmp = icmp ne <2 x i64> %and, zeroinitializer 77 ret <2 x i1> %cmp 78} 79 80define i1 @test_ne_cp2(i8 %x, i8 %yy) { 81; CHECK-LABEL: @test_ne_cp2( 82; CHECK-NEXT: [[AND_X_NEG_Y:%.*]] = and i8 [[X:%.*]], -16 83; CHECK-NEXT: [[AND_X_Y:%.*]] = and i8 [[X]], 16 84; CHECK-NEXT: call void @use.i8(i8 [[AND_X_NEG_Y]]) 85; CHECK-NEXT: call void @use.i8(i8 [[AND_X_Y]]) 86; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 31 87; CHECK-NEXT: ret i1 [[R]] 88; 89 %and_x_neg_y = and i8 %x, -16 90 %and_x_y = and i8 %x, 16 91 call void @use.i8(i8 %and_x_neg_y) 92 call void @use.i8(i8 %and_x_y) 93 %r = icmp ne i8 %and_x_neg_y, %and_x_y 94 ret i1 %r 95} 96 97define i1 @test_ne_cp2_2(i8 %x, i8 %yy) { 98; CHECK-LABEL: @test_ne_cp2_2( 99; CHECK-NEXT: [[AND_X_NEG_Y:%.*]] = and i8 [[X:%.*]], -4 100; CHECK-NEXT: [[AND_X_Y:%.*]] = and i8 [[X]], 4 101; CHECK-NEXT: call void @use.i8(i8 [[AND_X_NEG_Y]]) 102; CHECK-NEXT: call void @use.i8(i8 [[AND_X_Y]]) 103; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[X]], 8 104; CHECK-NEXT: ret i1 [[R]] 105; 106 %and_x_neg_y = and i8 %x, -4 107 %and_x_y = and i8 %x, 4 108 call void @use.i8(i8 %and_x_neg_y) 109 call void @use.i8(i8 %and_x_y) 110 %r = icmp eq i8 %and_x_y, %and_x_neg_y 111 ret i1 %r 112} 113 114define i1 @test_ne_cp2_other_okay_all_ones(i8 %x, i8 %yy) { 115; CHECK-LABEL: @test_ne_cp2_other_okay_all_ones( 116; CHECK-NEXT: [[AND_X_NEG_Y:%.*]] = and i8 [[X:%.*]], -17 117; CHECK-NEXT: [[AND_X_Y:%.*]] = and i8 [[X]], 16 118; CHECK-NEXT: call void @use.i8(i8 [[AND_X_NEG_Y]]) 119; CHECK-NEXT: call void @use.i8(i8 [[AND_X_Y]]) 120; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X]], 0 121; CHECK-NEXT: ret i1 [[R]] 122; 123 %and_x_neg_y = and i8 %x, -17 124 %and_x_y = and i8 %x, 16 125 call void @use.i8(i8 %and_x_neg_y) 126 call void @use.i8(i8 %and_x_y) 127 %r = icmp ne i8 %and_x_neg_y, %and_x_y 128 ret i1 %r 129} 130 131define i1 @test_ne_cp2_other_fail2(i8 %x, i8 %yy) { 132; CHECK-LABEL: @test_ne_cp2_other_fail2( 133; CHECK-NEXT: [[AND_X_NEG_Y:%.*]] = and i8 [[X:%.*]], -16 134; CHECK-NEXT: [[AND_X_Y:%.*]] = and i8 [[X]], 17 135; CHECK-NEXT: call void @use.i8(i8 [[AND_X_NEG_Y]]) 136; CHECK-NEXT: call void @use.i8(i8 [[AND_X_Y]]) 137; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND_X_NEG_Y]], [[AND_X_Y]] 138; CHECK-NEXT: ret i1 [[R]] 139; 140 %and_x_neg_y = and i8 %x, -16 141 %and_x_y = and i8 %x, 17 142 call void @use.i8(i8 %and_x_neg_y) 143 call void @use.i8(i8 %and_x_y) 144 %r = icmp ne i8 %and_x_neg_y, %and_x_y 145 ret i1 %r 146} 147 148define i1 @test_ne_cp2_other_okay(i8 %x, i8 %yy) { 149; CHECK-LABEL: @test_ne_cp2_other_okay( 150; CHECK-NEXT: [[AND_X_Y:%.*]] = and i8 [[X:%.*]], 16 151; CHECK-NEXT: call void @use.i8(i8 [[AND_X_Y]]) 152; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X]], 0 153; CHECK-NEXT: ret i1 [[R]] 154; 155 %and_x_neg_y = and i8 %x, -17 156 %and_x_y = and i8 %x, 16 157 call void @use.i8(i8 %and_x_y) 158 %r = icmp ne i8 %and_x_neg_y, %and_x_y 159 ret i1 %r 160} 161 162define i1 @test_ne_cp2_other_okay2(i8 %x, i8 %yy) { 163; CHECK-LABEL: @test_ne_cp2_other_okay2( 164; CHECK-NEXT: [[AND_X_Y:%.*]] = and i8 [[X:%.*]], 16 165; CHECK-NEXT: call void @use.i8(i8 [[AND_X_Y]]) 166; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X]], 0 167; CHECK-NEXT: ret i1 [[R]] 168; 169 %and_x_neg_y = and i8 %x, -17 170 %and_x_y = and i8 %x, 16 171 call void @use.i8(i8 %and_x_y) 172 %r = icmp ne i8 %and_x_y, %and_x_neg_y 173 ret i1 %r 174} 175 176define i1 @test_eq_0_and_15_add_1(i8 %a) { 177; CHECK-LABEL: @test_eq_0_and_15_add_1( 178; CHECK-NEXT: entry: 179; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15 180; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], 15 181; CHECK-NEXT: ret i1 [[CMP]] 182; 183entry: 184 %add = add i8 %a, 1 185 %and = and i8 %add, 15 186 %cmp = icmp eq i8 %and, 0 187 ret i1 %cmp 188} 189 190define i1 @test_ne_0_and_15_add_1(i8 %a) { 191; CHECK-LABEL: @test_ne_0_and_15_add_1( 192; CHECK-NEXT: entry: 193; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15 194; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP0]], 15 195; CHECK-NEXT: ret i1 [[CMP]] 196; 197entry: 198 %add = add i8 %a, 1 199 %and = and i8 %add, 15 200 %cmp = icmp ne i8 %and, 0 201 ret i1 %cmp 202} 203 204define i1 @test_eq_0_and_15_add_3(i8 %a) { 205; CHECK-LABEL: @test_eq_0_and_15_add_3( 206; CHECK-NEXT: entry: 207; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15 208; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], 13 209; CHECK-NEXT: ret i1 [[CMP]] 210; 211entry: 212 %add = add i8 %a, 3 213 %and = and i8 %add, 15 214 %cmp = icmp eq i8 %and, 0 215 ret i1 %cmp 216} 217 218define i1 @test_ne_0_and_15_add_3(i8 %a) { 219; CHECK-LABEL: @test_ne_0_and_15_add_3( 220; CHECK-NEXT: entry: 221; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15 222; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP0]], 13 223; CHECK-NEXT: ret i1 [[CMP]] 224; 225entry: 226 %add = add i8 %a, 3 227 %and = and i8 %add, 15 228 %cmp = icmp ne i8 %and, 0 229 ret i1 %cmp 230} 231 232define i1 @test_eq_11_and_15_add_10(i8 %a) { 233; CHECK-LABEL: @test_eq_11_and_15_add_10( 234; CHECK-NEXT: entry: 235; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15 236; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], 1 237; CHECK-NEXT: ret i1 [[CMP]] 238; 239entry: 240 %add = add i8 %a, 10 241 %and = and i8 %add, 15 242 %cmp = icmp eq i8 %and, 11 243 ret i1 %cmp 244} 245 246define i1 @test_ne_11_and_15_add_10(i8 %a) { 247; CHECK-LABEL: @test_ne_11_and_15_add_10( 248; CHECK-NEXT: entry: 249; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15 250; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP0]], 1 251; CHECK-NEXT: ret i1 [[CMP]] 252; 253entry: 254 %add = add i8 %a, 10 255 %and = and i8 %add, 15 256 %cmp = icmp ne i8 %and, 11 257 ret i1 %cmp 258} 259