237 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Simplify 'shl' inequality test into 'and' equality test.5; (X l<< C2) u</u>= C1 iff C1 is power of 2 -> X & (-C1 l>> C2) ==/!= 06 7; Scalar tests8 9; C2 Shift amount smaller than C1 trailing zeros.10define i1 @scalar_i8_shl_ult_const_1(i8 %x) {11; CHECK-LABEL: @scalar_i8_shl_ult_const_1(12; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 613; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 014; CHECK-NEXT: ret i1 [[CMP]]15;16 %shl = shl i8 %x, 517 %cmp = icmp ult i8 %shl, 6418 ret i1 %cmp19}20 21; C2 Shift amount equal to C1 trailing zeros.22define i1 @scalar_i8_shl_ult_const_2(i8 %x) {23; CHECK-LABEL: @scalar_i8_shl_ult_const_2(24; CHECK-NEXT: [[SHL_MASK:%.*]] = and i8 [[X:%.*]], 325; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHL_MASK]], 026; CHECK-NEXT: ret i1 [[CMP]]27;28 %shl = shl i8 %x, 629 %cmp = icmp ult i8 %shl, 6430 ret i1 %cmp31}32 33; C2 Shift amount greater than C1 trailing zeros.34define i1 @scalar_i8_shl_ult_const_3(i8 %x) {35; CHECK-LABEL: @scalar_i8_shl_ult_const_3(36; CHECK-NEXT: [[SHL_MASK:%.*]] = and i8 [[X:%.*]], 137; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHL_MASK]], 038; CHECK-NEXT: ret i1 [[CMP]]39;40 %shl = shl i8 %x, 741 %cmp = icmp ult i8 %shl, 6442 ret i1 %cmp43}44 45; C2 Shift amount smaller than C1 trailing zeros.46define i1 @scalar_i16_shl_ult_const(i16 %x) {47; CHECK-LABEL: @scalar_i16_shl_ult_const(48; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], 25249; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 050; CHECK-NEXT: ret i1 [[CMP]]51;52 %shl = shl i16 %x, 853 %cmp = icmp ult i16 %shl, 102454 ret i1 %cmp55}56 57define i1 @scalar_i32_shl_ult_const(i32 %x) {58; CHECK-LABEL: @scalar_i32_shl_ult_const(59; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 209708860; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 061; CHECK-NEXT: ret i1 [[CMP]]62;63 %shl = shl i32 %x, 1164 %cmp = icmp ult i32 %shl, 13107265 ret i1 %cmp66}67 68define i1 @scalar_i64_shl_ult_const(i64 %x) {69; CHECK-LABEL: @scalar_i64_shl_ult_const(70; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 54975581363271; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], 072; CHECK-NEXT: ret i1 [[CMP]]73;74 %shl = shl i64 %x, 2575 %cmp = icmp ult i64 %shl, 858993459276 ret i1 %cmp77}78 79; Check 'uge' predicate80define i1 @scalar_i8_shl_uge_const(i8 %x) {81; CHECK-LABEL: @scalar_i8_shl_uge_const(82; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 683; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 084; CHECK-NEXT: ret i1 [[CMP]]85;86 %shl = shl i8 %x, 587 %cmp = icmp uge i8 %shl, 6488 ret i1 %cmp89}90 91; Check 'ule' predicate92define i1 @scalar_i8_shl_ule_const(i8 %x) {93; CHECK-LABEL: @scalar_i8_shl_ule_const(94; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 695; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 096; CHECK-NEXT: ret i1 [[CMP]]97;98 %shl = shl i8 %x, 599 %cmp = icmp ule i8 %shl, 63100 ret i1 %cmp101}102 103; Check 'ugt' predicate104define i1 @scalar_i8_shl_ugt_const(i8 %x) {105; CHECK-LABEL: @scalar_i8_shl_ugt_const(106; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 6107; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 0108; CHECK-NEXT: ret i1 [[CMP]]109;110 %shl = shl i8 %x, 5111 %cmp = icmp ugt i8 %shl, 63112 ret i1 %cmp113}114 115; Vector tests116 117define <4 x i1> @vector_4xi32_shl_ult_const(<4 x i32> %x) {118; CHECK-LABEL: @vector_4xi32_shl_ult_const(119; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[X:%.*]], splat (i32 2097088)120; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[TMP1]], zeroinitializer121; CHECK-NEXT: ret <4 x i1> [[CMP]]122;123 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 11, i32 11>124 %cmp = icmp ult <4 x i32> %shl, <i32 131072, i32 131072, i32 131072, i32 131072>125 ret <4 x i1> %cmp126}127 128define <4 x i1> @vector_4xi32_shl_ult_const_undef1(<4 x i32> %x) {129; CHECK-LABEL: @vector_4xi32_shl_ult_const_undef1(130; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], <i32 11, i32 11, i32 undef, i32 11>131; CHECK-NEXT: [[CMP:%.*]] = icmp ult <4 x i32> [[SHL]], splat (i32 131072)132; CHECK-NEXT: ret <4 x i1> [[CMP]]133;134 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 undef, i32 11>135 %cmp = icmp ult <4 x i32> %shl, <i32 131072, i32 131072, i32 131072, i32 131072>136 ret <4 x i1> %cmp137}138 139define <4 x i1> @vector_4xi32_shl_ult_const_undef2(<4 x i32> %x) {140; CHECK-LABEL: @vector_4xi32_shl_ult_const_undef2(141; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], splat (i32 11)142; CHECK-NEXT: [[CMP:%.*]] = icmp ult <4 x i32> [[SHL]], <i32 131072, i32 131072, i32 131072, i32 undef>143; CHECK-NEXT: ret <4 x i1> [[CMP]]144;145 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 11, i32 11>146 %cmp = icmp ult <4 x i32> %shl, <i32 131072, i32 131072, i32 131072, i32 undef>147 ret <4 x i1> %cmp148}149 150define <4 x i1> @vector_4xi32_shl_ult_const_undef3(<4 x i32> %x) {151; CHECK-LABEL: @vector_4xi32_shl_ult_const_undef3(152; CHECK-NEXT: [[SHL:%.*]] = shl <4 x i32> [[X:%.*]], <i32 11, i32 11, i32 undef, i32 11>153; CHECK-NEXT: [[CMP:%.*]] = icmp ult <4 x i32> [[SHL]], <i32 undef, i32 131072, i32 131072, i32 131072>154; CHECK-NEXT: ret <4 x i1> [[CMP]]155;156 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 undef, i32 11>157 %cmp = icmp ult <4 x i32> %shl, <i32 undef, i32 131072, i32 131072, i32 131072>158 ret <4 x i1> %cmp159}160 161; Check 'uge' predicate162define <4 x i1> @vector_4xi32_shl_uge_const(<4 x i32> %x) {163; CHECK-LABEL: @vector_4xi32_shl_uge_const(164; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[X:%.*]], splat (i32 2097088)165; CHECK-NEXT: [[CMP:%.*]] = icmp ne <4 x i32> [[TMP1]], zeroinitializer166; CHECK-NEXT: ret <4 x i1> [[CMP]]167;168 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 11, i32 11>169 %cmp = icmp uge <4 x i32> %shl, <i32 131072, i32 131072, i32 131072, i32 131072>170 ret <4 x i1> %cmp171}172 173; Check 'ule' predicate174define <4 x i1> @vector_4xi32_shl_ule_const(<4 x i32> %x) {175; CHECK-LABEL: @vector_4xi32_shl_ule_const(176; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[X:%.*]], splat (i32 2097088)177; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[TMP1]], zeroinitializer178; CHECK-NEXT: ret <4 x i1> [[CMP]]179;180 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 11, i32 11>181 %cmp = icmp ule <4 x i32> %shl, <i32 131071, i32 131071, i32 131071, i32 131071>182 ret <4 x i1> %cmp183}184 185; Check 'ugt' predicate186define <4 x i1> @vector_4xi32_shl_ugt_const(<4 x i32> %x) {187; CHECK-LABEL: @vector_4xi32_shl_ugt_const(188; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[X:%.*]], splat (i32 2097088)189; CHECK-NEXT: [[CMP:%.*]] = icmp ne <4 x i32> [[TMP1]], zeroinitializer190; CHECK-NEXT: ret <4 x i1> [[CMP]]191;192 %shl = shl <4 x i32> %x, <i32 11, i32 11, i32 11, i32 11>193 %cmp = icmp ugt <4 x i32> %shl, <i32 131071, i32 131071, i32 131071, i32 131071>194 ret <4 x i1> %cmp195}196 197; Extra use198 199; Not simplified200define i1 @scalar_i8_shl_ult_const_extra_use_shl(i8 %x, ptr %p) {201; CHECK-LABEL: @scalar_i8_shl_ult_const_extra_use_shl(202; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 5203; CHECK-NEXT: store i8 [[SHL]], ptr [[P:%.*]], align 1204; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[SHL]], 64205; CHECK-NEXT: ret i1 [[CMP]]206;207 %shl = shl i8 %x, 5208 store i8 %shl, ptr %p209 %cmp = icmp ult i8 %shl, 64210 ret i1 %cmp211}212 213; Negative tests214 215; Check 'slt' predicate216define i1 @scalar_i8_shl_slt_const(i8 %x) {217; CHECK-LABEL: @scalar_i8_shl_slt_const(218; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 5219; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[SHL]], 64220; CHECK-NEXT: ret i1 [[CMP]]221;222 %shl = shl i8 %x, 5223 %cmp = icmp slt i8 %shl, 64224 ret i1 %cmp225}226 227define i1 @scalar_i8_shl_ugt_const_not_power_of_2(i8 %x) {228; CHECK-LABEL: @scalar_i8_shl_ugt_const_not_power_of_2(229; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 5230; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[SHL]], 66231; CHECK-NEXT: ret i1 [[CMP]]232;233 %shl = shl i8 %x, 5234 %cmp = icmp ugt i8 %shl, 66235 ret i1 %cmp236}237