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 l>> Y) & signbit) ==/!= 0 5; it may be optimal to fold into (X l>> Y) >=/< 0 6; rather than X & (signbit << Y) ==/!= 0 7 8; Scalar tests 9 10define i1 @scalar_i8_lshr_and_signbit_eq(i8 %x, i8 %y) { 11; CHECK-LABEL: @scalar_i8_lshr_and_signbit_eq( 12; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 [[X:%.*]], [[Y:%.*]] 13; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[LSHR]], -1 14; CHECK-NEXT: ret i1 [[R]] 15; 16 %lshr = lshr i8 %x, %y 17 %and = and i8 %lshr, 128 18 %r = icmp eq i8 %and, 0 19 ret i1 %r 20} 21 22define i1 @scalar_i16_lshr_and_signbit_eq(i16 %x, i16 %y) { 23; CHECK-LABEL: @scalar_i16_lshr_and_signbit_eq( 24; CHECK-NEXT: [[LSHR:%.*]] = lshr i16 [[X:%.*]], [[Y:%.*]] 25; CHECK-NEXT: [[R:%.*]] = icmp sgt i16 [[LSHR]], -1 26; CHECK-NEXT: ret i1 [[R]] 27; 28 %lshr = lshr i16 %x, %y 29 %and = and i16 %lshr, 32768 30 %r = icmp eq i16 %and, 0 31 ret i1 %r 32} 33 34define i1 @scalar_i32_lshr_and_signbit_eq(i32 %x, i32 %y) { 35; CHECK-LABEL: @scalar_i32_lshr_and_signbit_eq( 36; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 37; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[LSHR]], -1 38; CHECK-NEXT: ret i1 [[R]] 39; 40 %lshr = lshr i32 %x, %y 41 %and = and i32 %lshr, 2147483648 42 %r = icmp eq i32 %and, 0 43 ret i1 %r 44} 45 46define i1 @scalar_i64_lshr_and_signbit_eq(i64 %x, i64 %y) { 47; CHECK-LABEL: @scalar_i64_lshr_and_signbit_eq( 48; CHECK-NEXT: [[LSHR:%.*]] = lshr i64 [[X:%.*]], [[Y:%.*]] 49; CHECK-NEXT: [[R:%.*]] = icmp sgt i64 [[LSHR]], -1 50; CHECK-NEXT: ret i1 [[R]] 51; 52 %lshr = lshr i64 %x, %y 53 %and = and i64 %lshr, 9223372036854775808 54 %r = icmp eq i64 %and, 0 55 ret i1 %r 56} 57 58define i1 @scalar_i32_lshr_and_signbit_ne(i32 %x, i32 %y) { 59; CHECK-LABEL: @scalar_i32_lshr_and_signbit_ne( 60; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 61; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[LSHR]], 0 62; CHECK-NEXT: ret i1 [[R]] 63; 64 %lshr = lshr i32 %x, %y 65 %and = and i32 %lshr, 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_lshr_and_signbit_eq(<4 x i32> %x, <4 x i32> %y) { 73; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq( 74; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]] 75; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[LSHR]], <i32 -1, i32 -1, i32 -1, i32 -1> 76; CHECK-NEXT: ret <4 x i1> [[R]] 77; 78 %lshr = lshr <4 x i32> %x, %y 79 %and = and <4 x i32> %lshr, <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_lshr_and_signbit_eq_undef1(<4 x i32> %x, <4 x i32> %y) { 85; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq_undef1( 86; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]] 87; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], <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 %lshr = lshr <4 x i32> %x, %y 92 %and = and <4 x i32> %lshr, <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_lshr_and_signbit_eq_undef2(<4 x i32> %x, <4 x i32> %y) { 98; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq_undef2( 99; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]] 100; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], <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 %lshr = lshr <4 x i32> %x, %y 105 %and = and <4 x i32> %lshr, <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_lshr_and_signbit_eq_undef3(<4 x i32> %x, <4 x i32> %y) { 111; CHECK-LABEL: @vec_4xi32_lshr_and_signbit_eq_undef3( 112; CHECK-NEXT: [[LSHR:%.*]] = lshr <4 x i32> [[X:%.*]], [[Y:%.*]] 113; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[LSHR]], <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 %lshr = lshr <4 x i32> %x, %y 118 %and = and <4 x i32> %lshr, <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_lshr_and_signbit_eq_extra_use_lshr(i32 %x, i32 %y, i32 %z, i32* %p) { 127; CHECK-LABEL: @scalar_lshr_and_signbit_eq_extra_use_lshr( 128; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 129; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[LSHR]], [[Z:%.*]] 130; CHECK-NEXT: store i32 [[XOR]], i32* [[P:%.*]], align 4 131; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[LSHR]], -1 132; CHECK-NEXT: ret i1 [[R]] 133; 134 %lshr = lshr i32 %x, %y 135 %xor = xor i32 %lshr, %z ; extra use of lshr 136 store i32 %xor, i32* %p 137 %and = and i32 %lshr, 2147483648 138 %r = icmp eq i32 %and, 0 139 ret i1 %r 140} 141 142; Not fold 143define i1 @scalar_lshr_and_signbit_eq_extra_use_and(i32 %x, i32 %y, i32 %z, i32* %p) { 144; CHECK-LABEL: @scalar_lshr_and_signbit_eq_extra_use_and( 145; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 146; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], -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 %lshr = lshr i32 %x, %y 153 %and = and i32 %lshr, 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_lshr_and_signbit_eq_extra_use_lshr_and(i32 %x, i32 %y, i32 %z, i32* %p, i32* %q) { 162; CHECK-LABEL: @scalar_lshr_and_signbit_eq_extra_use_lshr_and( 163; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 164; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], -2147483648 165; CHECK-NEXT: store i32 [[AND]], i32* [[P:%.*]], align 4 166; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LSHR]], [[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 %lshr = lshr i32 %x, %y 172 %and = and i32 %lshr, 2147483648 173 store i32 %and, i32* %p ; extra use of and 174 %add = add i32 %lshr, %z ; extra use of lshr 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_lshr_and_signbit_eq_X_is_constant1(i32 %y) { 185; CHECK-LABEL: @scalar_i32_lshr_and_signbit_eq_X_is_constant1( 186; CHECK-NEXT: ret i1 true 187; 188 %lshr = lshr i32 12345, %y 189 %and = and i32 %lshr, 2147483648 190 %r = icmp eq i32 %and, 0 191 ret i1 %r 192} 193 194define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant2(i32 %y) { 195; CHECK-LABEL: @scalar_i32_lshr_and_negC_eq_X_is_constant2( 196; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 -2147483648, [[Y:%.*]] 197; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[LSHR]], -1 198; CHECK-NEXT: ret i1 [[R]] 199; 200 %lshr = lshr i32 2147483648, %y 201 %and = and i32 %lshr, 2147483648 202 %r = icmp eq i32 %and, 0 203 ret i1 %r 204} 205 206; Check 'slt' predicate 207 208define i1 @scalar_i32_lshr_and_negC_slt(i32 %x, i32 %y) { 209; CHECK-LABEL: @scalar_i32_lshr_and_negC_slt( 210; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 211; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[LSHR]], 0 212; CHECK-NEXT: ret i1 [[R]] 213; 214 %lshr = lshr i32 %x, %y 215 %and = and i32 %lshr, 2147483648 216 %r = icmp slt i32 %and, 0 217 ret i1 %r 218} 219 220; Compare with nonzero 221 222define i1 @scalar_i32_lshr_and_negC_eq_nonzero(i32 %x, i32 %y) { 223; CHECK-LABEL: @scalar_i32_lshr_and_negC_eq_nonzero( 224; CHECK-NEXT: ret i1 false 225; 226 %lshr = lshr i32 %x, %y 227 %and = and i32 %lshr, 2147483648 228 %r = icmp eq i32 %and, 1 ; should be comparing with 0 229 ret i1 %r 230} 231