1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; For pattern ((X << Y) & signbit) ==/!= 0 5; it may be optimal to fold into (X << Y) >=/< 0 6; rather than X & (signbit l>> Y) ==/!= 0 7 8; Scalar tests 9 10define i1 @scalar_i8_shl_and_signbit_eq(i8 %x, i8 %y) { 11; CHECK-LABEL: @scalar_i8_shl_and_signbit_eq( 12; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], [[Y:%.*]] 13; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[SHL]], -1 14; CHECK-NEXT: ret i1 [[R]] 15; 16 %shl = shl i8 %x, %y 17 %and = and i8 %shl, 128 18 %r = icmp eq i8 %and, 0 19 ret i1 %r 20} 21 22define i1 @scalar_i16_shl_and_signbit_eq(i16 %x, i16 %y) { 23; CHECK-LABEL: @scalar_i16_shl_and_signbit_eq( 24; CHECK-NEXT: [[SHL:%.*]] = shl i16 [[X:%.*]], [[Y:%.*]] 25; CHECK-NEXT: [[R:%.*]] = icmp sgt i16 [[SHL]], -1 26; CHECK-NEXT: ret i1 [[R]] 27; 28 %shl = shl i16 %x, %y 29 %and = and i16 %shl, 32768 30 %r = icmp eq i16 %and, 0 31 ret i1 %r 32} 33 34define i1 @scalar_i32_shl_and_signbit_eq(i32 %x, i32 %y) { 35; CHECK-LABEL: @scalar_i32_shl_and_signbit_eq( 36; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]] 37; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[SHL]], -1 38; CHECK-NEXT: ret i1 [[R]] 39; 40 %shl = shl i32 %x, %y 41 %and = and i32 %shl, 2147483648 42 %r = icmp eq i32 %and, 0 43 ret i1 %r 44} 45 46define i1 @scalar_i64_shl_and_signbit_eq(i64 %x, i64 %y) { 47; CHECK-LABEL: @scalar_i64_shl_and_signbit_eq( 48; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X:%.*]], [[Y:%.*]] 49; CHECK-NEXT: [[R:%.*]] = icmp sgt i64 [[SHL]], -1 50; CHECK-NEXT: ret i1 [[R]] 51; 52 %shl = shl i64 %x, %y 53 %and = and i64 %shl, 9223372036854775808 54 %r = icmp eq i64 %and, 0 55 ret i1 %r 56} 57 58define i1 @scalar_i32_shl_and_signbit_ne(i32 %x, i32 %y) { 59; CHECK-LABEL: @scalar_i32_shl_and_signbit_ne( 60; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]] 61; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[SHL]], 0 62; CHECK-NEXT: ret i1 [[R]] 63; 64 %shl = shl i32 %x, %y 65 %and = and i32 %shl, 2147483648 66 %r = icmp ne i32 %and, 0 ; check 'ne' predicate 67 ret i1 %r 68} 69 70; Vector tests 71 72define <4 x i1> @vec_4xi32_shl_and_signbit_eq(<4 x i32> %x, <4 x i32> %y) { 73; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq( 74; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]] 75; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[SHL]], <i32 -1, i32 -1, i32 -1, i32 -1> 76; CHECK-NEXT: ret <4 x i1> [[R]] 77; 78 %shl = shl <4 x i32> %x, %y 79 %and = and <4 x i32> %shl, <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648> 80 %r = icmp eq <4 x i32> %and, <i32 0, i32 0, i32 0, i32 0> 81 ret <4 x i1> %r 82} 83 84define <4 x i1> @vec_4xi32_shl_and_signbit_eq_undef1(<4 x i32> %x, <4 x i32> %y) { 85; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq_undef1( 86; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]] 87; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], <i32 -2147483648, i32 undef, i32 -2147483648, i32 -2147483648> 88; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], zeroinitializer 89; CHECK-NEXT: ret <4 x i1> [[R]] 90; 91 %shl = shl <4 x i32> %x, %y 92 %and = and <4 x i32> %shl, <i32 2147483648, i32 undef, i32 2147483648, i32 2147483648> 93 %r = icmp eq <4 x i32> %and, <i32 0, i32 0, i32 0, i32 0> 94 ret <4 x i1> %r 95} 96 97define <4 x i1> @vec_4xi32_shl_and_signbit_eq_undef2(<4 x i32> %x, <4 x i32> %y) { 98; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq_undef2( 99; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]] 100; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 101; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 undef, i32 0, i32 0, i32 0> 102; CHECK-NEXT: ret <4 x i1> [[R]] 103; 104 %shl = shl <4 x i32> %x, %y 105 %and = and <4 x i32> %shl, <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648> 106 %r = icmp eq <4 x i32> %and, <i32 undef, i32 0, i32 0, i32 0> 107 ret <4 x i1> %r 108} 109 110define <4 x i1> @vec_4xi32_shl_and_signbit_eq_undef3(<4 x i32> %x, <4 x i32> %y) { 111; CHECK-LABEL: @vec_4xi32_shl_and_signbit_eq_undef3( 112; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], [[Y:%.*]] 113; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[SHL]], <i32 -2147483648, i32 undef, i32 -2147483648, i32 -2147483648> 114; CHECK-NEXT: [[R:%.*]] = icmp eq <4 x i32> [[AND]], <i32 0, i32 0, i32 0, i32 undef> 115; CHECK-NEXT: ret <4 x i1> [[R]] 116; 117 %shl = shl <4 x i32> %x, %y 118 %and = and <4 x i32> %shl, <i32 2147483648, i32 undef, i32 2147483648, i32 2147483648> 119 %r = icmp eq <4 x i32> %and, <i32 0, i32 0, i32 0, i32 undef> 120 ret <4 x i1> %r 121} 122 123; Extra use 124 125; Fold happened 126define i1 @scalar_shl_and_signbit_eq_extra_use_shl(i32 %x, i32 %y, i32 %z, i32* %p) { 127; CHECK-LABEL: @scalar_shl_and_signbit_eq_extra_use_shl( 128; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]] 129; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[SHL]], [[Z:%.*]] 130; CHECK-NEXT: store i32 [[XOR]], i32* [[P:%.*]], align 4 131; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[SHL]], -1 132; CHECK-NEXT: ret i1 [[R]] 133; 134 %shl = shl i32 %x, %y 135 %xor = xor i32 %shl, %z ; extra use of shl 136 store i32 %xor, i32* %p 137 %and = and i32 %shl, 2147483648 138 %r = icmp eq i32 %and, 0 139 ret i1 %r 140} 141 142; Not fold 143define i1 @scalar_shl_and_signbit_eq_extra_use_and(i32 %x, i32 %y, i32 %z, i32* %p) { 144; CHECK-LABEL: @scalar_shl_and_signbit_eq_extra_use_and( 145; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]] 146; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], -2147483648 147; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[AND]], [[Z:%.*]] 148; CHECK-NEXT: store i32 [[MUL]], i32* [[P:%.*]], align 4 149; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0 150; CHECK-NEXT: ret i1 [[R]] 151; 152 %shl = shl i32 %x, %y 153 %and = and i32 %shl, 2147483648 154 %mul = mul i32 %and, %z ; extra use of and 155 store i32 %mul, i32* %p 156 %r = icmp eq i32 %and, 0 157 ret i1 %r 158} 159 160; Not fold 161define i1 @scalar_shl_and_signbit_eq_extra_use_shl_and(i32 %x, i32 %y, i32 %z, i32* %p, i32* %q) { 162; CHECK-LABEL: @scalar_shl_and_signbit_eq_extra_use_shl_and( 163; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]] 164; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], -2147483648 165; CHECK-NEXT: store i32 [[AND]], i32* [[P:%.*]], align 4 166; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHL]], [[Z:%.*]] 167; CHECK-NEXT: store i32 [[ADD]], i32* [[Q:%.*]], align 4 168; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0 169; CHECK-NEXT: ret i1 [[R]] 170; 171 %shl = shl i32 %x, %y 172 %and = and i32 %shl, 2147483648 173 store i32 %and, i32* %p ; extra use of and 174 %add = add i32 %shl, %z ; extra use of shl 175 store i32 %add, i32* %q 176 %r = icmp eq i32 %and, 0 177 ret i1 %r 178} 179 180; Negative tests 181 182; X is constant 183 184define i1 @scalar_i32_shl_and_signbit_eq_X_is_constant1(i32 %y) { 185; CHECK-LABEL: @scalar_i32_shl_and_signbit_eq_X_is_constant1( 186; CHECK-NEXT: [[SHL:%.*]] = shl i32 12345, [[Y:%.*]] 187; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[SHL]], -1 188; CHECK-NEXT: ret i1 [[R]] 189; 190 %shl = shl i32 12345, %y 191 %and = and i32 %shl, 2147483648 192 %r = icmp eq i32 %and, 0 193 ret i1 %r 194} 195 196define i1 @scalar_i32_shl_and_signbit_eq_X_is_constant2(i32 %y) { 197; CHECK-LABEL: @scalar_i32_shl_and_signbit_eq_X_is_constant2( 198; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[Y:%.*]], 31 199; CHECK-NEXT: ret i1 [[R]] 200; 201 %shl = shl i32 1, %y 202 %and = and i32 %shl, 2147483648 203 %r = icmp eq i32 %and, 0 204 ret i1 %r 205} 206 207; Check 'slt' predicate 208 209define i1 @scalar_i32_shl_and_signbit_slt(i32 %x, i32 %y) { 210; CHECK-LABEL: @scalar_i32_shl_and_signbit_slt( 211; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]] 212; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[SHL]], 0 213; CHECK-NEXT: ret i1 [[R]] 214; 215 %shl = shl i32 %x, %y 216 %and = and i32 %shl, 2147483648 217 %r = icmp slt i32 %and, 0 218 ret i1 %r 219} 220 221; Compare with nonzero 222 223define i1 @scalar_i32_shl_and_signbit_eq_nonzero(i32 %x, i32 %y) { 224; CHECK-LABEL: @scalar_i32_shl_and_signbit_eq_nonzero( 225; CHECK-NEXT: ret i1 false 226; 227 %shl = shl i32 %x, %y 228 %and = and i32 %shl, 2147483648 229 %r = icmp eq i32 %and, 1 ; should be comparing with 0 230 ret i1 %r 231} 232