brintos

brintos / llvm-project-archived public Read only

0
0
Text · 25.2 KiB · e133533 Raw
739 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Canonicalize vector ge/le comparisons with constants to gt/lt.5 6; Normal types are ConstantDataVectors. Test the constant values adjacent to the7; min/max values that we're not allowed to transform.8 9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"10 11define <2 x i1> @sge(<2 x i8> %x) {12; CHECK-LABEL: @sge(13; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], <i8 -128, i8 126>14; CHECK-NEXT:    ret <2 x i1> [[CMP]]15;16  %cmp = icmp sge <2 x i8> %x, <i8 -127, i8 -129>17  ret <2 x i1> %cmp18}19 20define <2 x i1> @uge(<2 x i8> %x) {21; CHECK-LABEL: @uge(22; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 -2, i8 0>23; CHECK-NEXT:    ret <2 x i1> [[CMP]]24;25  %cmp = icmp uge <2 x i8> %x, <i8 -1, i8 1>26  ret <2 x i1> %cmp27}28 29define <2 x i1> @sle(<2 x i8> %x) {30; CHECK-LABEL: @sle(31; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], <i8 127, i8 -127>32; CHECK-NEXT:    ret <2 x i1> [[CMP]]33;34  %cmp = icmp sle <2 x i8> %x, <i8 126, i8 128>35  ret <2 x i1> %cmp36}37 38define <2 x i1> @ule(<2 x i8> %x) {39; CHECK-LABEL: @ule(40; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 -1, i8 1>41; CHECK-NEXT:    ret <2 x i1> [[CMP]]42;43  %cmp = icmp ule <2 x i8> %x, <i8 254, i8 0>44  ret <2 x i1> %cmp45}46 47define <2 x i1> @ult_min_signed_value(<2 x i8> %x) {48; CHECK-LABEL: @ult_min_signed_value(49; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1)50; CHECK-NEXT:    ret <2 x i1> [[CMP]]51;52  %cmp = icmp ult <2 x i8> %x, <i8 128, i8 128>53  ret <2 x i1> %cmp54}55 56; Zeros are special: they're ConstantAggregateZero.57 58define <2 x i1> @sge_zero(<2 x i8> %x) {59; CHECK-LABEL: @sge_zero(60; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1)61; CHECK-NEXT:    ret <2 x i1> [[CMP]]62;63  %cmp = icmp sge <2 x i8> %x, <i8 0, i8 0>64  ret <2 x i1> %cmp65}66 67define <2 x i1> @uge_zero(<2 x i8> %x) {68; CHECK-LABEL: @uge_zero(69; CHECK-NEXT:    ret <2 x i1> splat (i1 true)70;71  %cmp = icmp uge <2 x i8> %x, <i8 0, i8 0>72  ret <2 x i1> %cmp73}74 75define <2 x i1> @sle_zero(<2 x i8> %x) {76; CHECK-LABEL: @sle_zero(77; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], splat (i8 1)78; CHECK-NEXT:    ret <2 x i1> [[CMP]]79;80  %cmp = icmp sle <2 x i8> %x, <i8 0, i8 0>81  ret <2 x i1> %cmp82}83 84define <2 x i1> @ule_zero(<2 x i8> %x) {85; CHECK-LABEL: @ule_zero(86; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer87; CHECK-NEXT:    ret <2 x i1> [[CMP]]88;89  %cmp = icmp ule <2 x i8> %x, <i8 0, i8 0>90  ret <2 x i1> %cmp91}92 93; Weird types are ConstantVectors, not ConstantDataVectors. For an i3 type:94; Signed min = -495; Unsigned min = 096; Signed max = 397; Unsigned max = 798 99define <3 x i1> @sge_weird(<3 x i3> %x) {100; CHECK-LABEL: @sge_weird(101; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <3 x i3> [[X:%.*]], <i3 -4, i3 2, i3 -1>102; CHECK-NEXT:    ret <3 x i1> [[CMP]]103;104  %cmp = icmp sge <3 x i3> %x, <i3 -3, i3 -5, i3 0>105  ret <3 x i1> %cmp106}107 108define <3 x i1> @uge_weird(<3 x i3> %x) {109; CHECK-LABEL: @uge_weird(110; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <3 x i3> [[X:%.*]], <i3 -2, i3 0, i3 1>111; CHECK-NEXT:    ret <3 x i1> [[CMP]]112;113  %cmp = icmp uge <3 x i3> %x, <i3 -1, i3 1, i3 2>114  ret <3 x i1> %cmp115}116 117define <3 x i1> @sle_weird(<3 x i3> %x) {118; CHECK-LABEL: @sle_weird(119; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <3 x i3> [[X:%.*]], <i3 3, i3 -3, i3 1>120; CHECK-NEXT:    ret <3 x i1> [[CMP]]121;122  %cmp = icmp sle <3 x i3> %x, <i3 2, i3 4, i3 0>123  ret <3 x i1> %cmp124}125 126define <3 x i1> @ule_weird(<3 x i3> %x) {127; CHECK-LABEL: @ule_weird(128; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <3 x i3> [[X:%.*]], <i3 -1, i3 1, i3 2>129; CHECK-NEXT:    ret <3 x i1> [[CMP]]130;131  %cmp = icmp ule <3 x i3> %x, <i3 6, i3 0, i3 1>132  ret <3 x i1> %cmp133}134 135; We can't do the transform if any constants are already at the limits.136 137define <2 x i1> @sge_min(<2 x i3> %x) {138; CHECK-LABEL: @sge_min(139; CHECK-NEXT:    [[CMP:%.*]] = icmp sge <2 x i3> [[X:%.*]], <i3 -4, i3 1>140; CHECK-NEXT:    ret <2 x i1> [[CMP]]141;142  %cmp = icmp sge <2 x i3> %x, <i3 -4, i3 1>143  ret <2 x i1> %cmp144}145 146define <2 x i1> @uge_min(<2 x i3> %x) {147; CHECK-LABEL: @uge_min(148; CHECK-NEXT:    [[CMP:%.*]] = icmp uge <2 x i3> [[X:%.*]], <i3 1, i3 0>149; CHECK-NEXT:    ret <2 x i1> [[CMP]]150;151  %cmp = icmp uge <2 x i3> %x, <i3 1, i3 0>152  ret <2 x i1> %cmp153}154 155define <2 x i1> @sle_max(<2 x i3> %x) {156; CHECK-LABEL: @sle_max(157; CHECK-NEXT:    [[CMP:%.*]] = icmp sle <2 x i3> [[X:%.*]], <i3 1, i3 3>158; CHECK-NEXT:    ret <2 x i1> [[CMP]]159;160  %cmp = icmp sle <2 x i3> %x, <i3 1, i3 3>161  ret <2 x i1> %cmp162}163 164define <2 x i1> @ule_max(<2 x i3> %x) {165; CHECK-LABEL: @ule_max(166; CHECK-NEXT:    [[CMP:%.*]] = icmp ule <2 x i3> [[X:%.*]], <i3 -1, i3 1>167; CHECK-NEXT:    ret <2 x i1> [[CMP]]168;169  %cmp = icmp ule <2 x i3> %x, <i3 7, i3 1>170  ret <2 x i1> %cmp171}172 173define <2 x i1> @PR27756_1(<2 x i8> %a) {174; CHECK-LABEL: @PR27756_1(175; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], <i8 34, i8 1>176; CHECK-NEXT:    ret <2 x i1> [[CMP]]177;178  %cmp = icmp sle <2 x i8> %a, <i8 bitcast (<2 x i4> <i4 1, i4 2> to i8), i8 0>179  ret <2 x i1> %cmp180}181 182; Undef elements don't prevent the transform of the comparison.183 184define <3 x i1> @PR27756_2(<3 x i8> %a) {185; CHECK-LABEL: @PR27756_2(186; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <3 x i8> [[A:%.*]], <i8 43, i8 43, i8 1>187; CHECK-NEXT:    ret <3 x i1> [[CMP]]188;189  %cmp = icmp sle <3 x i8> %a, <i8 42, i8 poison, i8 0>190  ret <3 x i1> %cmp191}192 193define <3 x i1> @PR27756_3(<3 x i8> %a) {194; CHECK-LABEL: @PR27756_3(195; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <3 x i8> [[A:%.*]], <i8 0, i8 0, i8 41>196; CHECK-NEXT:    ret <3 x i1> [[CMP]]197;198  %cmp = icmp sge <3 x i8> %a, <i8 poison, i8 1, i8 42>199  ret <3 x i1> %cmp200}201 202@someglobal = global i32 0203 204define <2 x i1> @PR27786(<2 x i8> %a) {205; CHECK-LABEL: @PR27786(206; CHECK-NEXT:    [[CMP:%.*]] = icmp sle <2 x i8> [[A:%.*]], bitcast (i16 ptrtoint (ptr @someglobal to i16) to <2 x i8>)207; CHECK-NEXT:    ret <2 x i1> [[CMP]]208;209  %cmp = icmp sle <2 x i8> %a, bitcast (i16 ptrtoint (ptr @someglobal to i16) to <2 x i8>)210  ret <2 x i1> %cmp211}212 213; This is similar to a transform for shuffled binops: compare first, shuffle after.214 215define <4 x i1> @same_shuffle_inputs_icmp(<4 x i8> %x, <4 x i8> %y) {216; CHECK-LABEL: @same_shuffle_inputs_icmp(217; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i8> [[X:%.*]], [[Y:%.*]]218; CHECK-NEXT:    [[CMP:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> poison, <4 x i32> <i32 3, i32 3, i32 2, i32 0>219; CHECK-NEXT:    ret <4 x i1> [[CMP]]220;221  %shufx = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> < i32 3, i32 3, i32 2, i32 0 >222  %shufy = shufflevector <4 x i8> %y, <4 x i8> poison, <4 x i32> < i32 3, i32 3, i32 2, i32 0 >223  %cmp = icmp sgt <4 x i8> %shufx, %shufy224  ret <4 x i1> %cmp225}226 227; fcmp and size-changing shuffles are ok too.228 229define <5 x i1> @same_shuffle_inputs_fcmp(<4 x float> %x, <4 x float> %y) {230; CHECK-LABEL: @same_shuffle_inputs_fcmp(231; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq <4 x float> [[X:%.*]], [[Y:%.*]]232; CHECK-NEXT:    [[CMP:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> poison, <5 x i32> <i32 0, i32 1, i32 3, i32 2, i32 0>233; CHECK-NEXT:    ret <5 x i1> [[CMP]]234;235  %shufx = shufflevector <4 x float> %x, <4 x float> poison, <5 x i32> < i32 0, i32 1, i32 3, i32 2, i32 0 >236  %shufy = shufflevector <4 x float> %y, <4 x float> poison, <5 x i32> < i32 0, i32 1, i32 3, i32 2, i32 0 >237  %cmp = fcmp oeq <5 x float> %shufx, %shufy238  ret <5 x i1> %cmp239}240 241declare void @use_v4i8(<4 x i8>)242 243define <4 x i1> @same_shuffle_inputs_icmp_extra_use1(<4 x i8> %x, <4 x i8> %y) {244; CHECK-LABEL: @same_shuffle_inputs_icmp_extra_use1(245; CHECK-NEXT:    [[SHUFX:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3>246; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt <4 x i8> [[X]], [[Y:%.*]]247; CHECK-NEXT:    [[CMP:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3>248; CHECK-NEXT:    call void @use_v4i8(<4 x i8> [[SHUFX]])249; CHECK-NEXT:    ret <4 x i1> [[CMP]]250;251  %shufx = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> < i32 3, i32 3, i32 3, i32 3 >252  %shufy = shufflevector <4 x i8> %y, <4 x i8> poison, <4 x i32> < i32 3, i32 3, i32 3, i32 3 >253  %cmp = icmp ugt <4 x i8> %shufx, %shufy254  call void @use_v4i8(<4 x i8> %shufx)255  ret <4 x i1> %cmp256}257 258declare void @use_v2i8(<2 x i8>)259 260define <2 x i1> @same_shuffle_inputs_icmp_extra_use2(<4 x i8> %x, <4 x i8> %y) {261; CHECK-LABEL: @same_shuffle_inputs_icmp_extra_use2(262; CHECK-NEXT:    [[SHUFY:%.*]] = shufflevector <4 x i8> [[Y:%.*]], <4 x i8> poison, <2 x i32> <i32 3, i32 2>263; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <4 x i8> [[X:%.*]], [[Y]]264; CHECK-NEXT:    [[CMP:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> poison, <2 x i32> <i32 3, i32 2>265; CHECK-NEXT:    call void @use_v2i8(<2 x i8> [[SHUFY]])266; CHECK-NEXT:    ret <2 x i1> [[CMP]]267;268  %shufx = shufflevector <4 x i8> %x, <4 x i8> poison, <2 x i32> < i32 3, i32 2 >269  %shufy = shufflevector <4 x i8> %y, <4 x i8> poison, <2 x i32> < i32 3, i32 2 >270  %cmp = icmp eq <2 x i8> %shufx, %shufy271  call void @use_v2i8(<2 x i8> %shufy)272  ret <2 x i1> %cmp273}274 275; Negative test: if both shuffles have extra uses, don't transform because that would increase instruction count.276 277define <2 x i1> @same_shuffle_inputs_icmp_extra_use3(<4 x i8> %x, <4 x i8> %y) {278; CHECK-LABEL: @same_shuffle_inputs_icmp_extra_use3(279; CHECK-NEXT:    [[SHUFX:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> poison, <2 x i32> zeroinitializer280; CHECK-NEXT:    [[SHUFY:%.*]] = shufflevector <4 x i8> [[Y:%.*]], <4 x i8> poison, <2 x i32> zeroinitializer281; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[SHUFX]], [[SHUFY]]282; CHECK-NEXT:    call void @use_v2i8(<2 x i8> [[SHUFX]])283; CHECK-NEXT:    call void @use_v2i8(<2 x i8> [[SHUFY]])284; CHECK-NEXT:    ret <2 x i1> [[CMP]]285;286  %shufx = shufflevector <4 x i8> %x, <4 x i8> poison, <2 x i32> < i32 0, i32 0 >287  %shufy = shufflevector <4 x i8> %y, <4 x i8> poison, <2 x i32> < i32 0, i32 0 >288  %cmp = icmp eq <2 x i8> %shufx, %shufy289  call void @use_v2i8(<2 x i8> %shufx)290  call void @use_v2i8(<2 x i8> %shufy)291  ret <2 x i1> %cmp292}293 294define <4 x i1> @splat_icmp(<4 x i8> %x) {295; CHECK-LABEL: @splat_icmp(296; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i8> [[X:%.*]], splat (i8 42)297; CHECK-NEXT:    [[CMP:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3>298; CHECK-NEXT:    ret <4 x i1> [[CMP]]299;300  %splatx = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3>301  %cmp = icmp sgt <4 x i8> %splatx, <i8 42, i8 42, i8 42, i8 42>302  ret <4 x i1> %cmp303}304 305define <4 x i1> @splat_icmp_poison(<4 x i8> %x) {306; CHECK-LABEL: @splat_icmp_poison(307; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult <4 x i8> [[X:%.*]], splat (i8 42)308; CHECK-NEXT:    [[CMP:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> poison, <4 x i32> <i32 2, i32 2, i32 2, i32 2>309; CHECK-NEXT:    ret <4 x i1> [[CMP]]310;311  %splatx = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> <i32 2, i32 poison, i32 poison, i32 2>312  %cmp = icmp ult <4 x i8> %splatx, <i8 poison, i8 42, i8 poison, i8 42>313  ret <4 x i1> %cmp314}315 316define <4 x i1> @splat_icmp_larger_size(<2 x i8> %x) {317; CHECK-LABEL: @splat_icmp_larger_size(318; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 42)319; CHECK-NEXT:    [[CMP:%.*]] = shufflevector <2 x i1> [[TMP1]], <2 x i1> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>320; CHECK-NEXT:    ret <4 x i1> [[CMP]]321;322  %splatx = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 1, i32 poison, i32 1, i32 poison>323  %cmp = icmp eq <4 x i8> %splatx, <i8 42, i8 42, i8 poison, i8 42>324  ret <4 x i1> %cmp325}326 327define <4 x i1> @splat_fcmp_smaller_size(<5 x float> %x) {328; CHECK-LABEL: @splat_fcmp_smaller_size(329; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq <5 x float> [[X:%.*]], splat (float 4.200000e+01)330; CHECK-NEXT:    [[CMP:%.*]] = shufflevector <5 x i1> [[TMP1]], <5 x i1> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>331; CHECK-NEXT:    ret <4 x i1> [[CMP]]332;333  %splatx = shufflevector <5 x float> %x, <5 x float> poison, <4 x i32> <i32 1, i32 poison, i32 1, i32 poison>334  %cmp = fcmp oeq <4 x float> %splatx, <float 42.0, float 42.0, float poison, float 42.0>335  ret <4 x i1> %cmp336}337 338; Negative test339 340define <4 x i1> @splat_icmp_extra_use(<4 x i8> %x) {341; CHECK-LABEL: @splat_icmp_extra_use(342; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3>343; CHECK-NEXT:    call void @use_v4i8(<4 x i8> [[SPLATX]])344; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <4 x i8> [[SPLATX]], splat (i8 42)345; CHECK-NEXT:    ret <4 x i1> [[CMP]]346;347  %splatx = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3>348  call void @use_v4i8(<4 x i8> %splatx)349  %cmp = icmp sgt <4 x i8> %splatx, <i8 42, i8 42, i8 42, i8 42>350  ret <4 x i1> %cmp351}352 353; Negative test354 355define <4 x i1> @not_splat_icmp(<4 x i8> %x) {356; CHECK-LABEL: @not_splat_icmp(357; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> poison, <4 x i32> <i32 3, i32 2, i32 3, i32 3>358; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <4 x i8> [[SPLATX]], splat (i8 42)359; CHECK-NEXT:    ret <4 x i1> [[CMP]]360;361  %splatx = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> <i32 3, i32 2, i32 3, i32 3>362  %cmp = icmp sgt <4 x i8> %splatx, <i8 42, i8 42, i8 42, i8 42>363  ret <4 x i1> %cmp364}365 366; Negative test367 368define <4 x i1> @not_splat_icmp2(<4 x i8> %x) {369; CHECK-LABEL: @not_splat_icmp2(370; CHECK-NEXT:    [[SPLATX:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> poison, <4 x i32> <i32 2, i32 2, i32 2, i32 2>371; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <4 x i8> [[SPLATX]], <i8 43, i8 42, i8 42, i8 42>372; CHECK-NEXT:    ret <4 x i1> [[CMP]]373;374  %splatx = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> <i32 2, i32 2, i32 2, i32 2>375  %cmp = icmp sgt <4 x i8> %splatx, <i8 43, i8 42, i8 42, i8 42>376  ret <4 x i1> %cmp377}378 379; Check that we don't absorb the compare into the select, which is in the380; canonical form of logical or.381define <2 x i1> @icmp_logical_or_vec(<2 x i64> %x, <2 x i64> %y, <2 x i1> %falseval) {382; CHECK-LABEL: @icmp_logical_or_vec(383; CHECK-NEXT:    [[CMP_NE:%.*]] = icmp ne <2 x i64> [[X:%.*]], zeroinitializer384; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP_NE]], <2 x i1> splat (i1 true), <2 x i1> [[FALSEVAL:%.*]]385; CHECK-NEXT:    ret <2 x i1> [[SEL]]386;387  %cmp.ne = icmp ne <2 x i64> %x, zeroinitializer388  %sel = select <2 x i1> %cmp.ne, <2 x i1> shufflevector (<2 x i1> insertelement (<2 x i1> poison, i1 true, i32 0), <2 x i1> poison, <2 x i32> zeroinitializer), <2 x i1> %falseval389  ret <2 x i1> %sel390}391 392; The above, but for scalable vectors. Absorbing the compare into the select393; and breaking the canonical form led to an infinite loop.394define <vscale x 2 x i1> @icmp_logical_or_scalablevec(<vscale x 2 x i64> %x, <vscale x 2 x i64> %y, <vscale x 2 x i1> %falseval) {395; CHECK-LABEL: @icmp_logical_or_scalablevec(396; CHECK-NEXT:    [[CMP_NE:%.*]] = icmp ne <vscale x 2 x i64> [[X:%.*]], zeroinitializer397; CHECK-NEXT:    [[SEL:%.*]] = select <vscale x 2 x i1> [[CMP_NE]], <vscale x 2 x i1> splat (i1 true), <vscale x 2 x i1> [[FALSEVAL:%.*]]398; CHECK-NEXT:    ret <vscale x 2 x i1> [[SEL]]399;400  %cmp.ne = icmp ne <vscale x 2 x i64> %x, zeroinitializer401  %sel = select <vscale x 2 x i1> %cmp.ne, <vscale x 2 x i1> splat (i1 true), <vscale x 2 x i1> %falseval402  ret <vscale x 2 x i1> %sel403}404 405define i1 @eq_cast_eq-1(<2 x i4> %x, <2 x i4> %y) {406; CHECK-LABEL: @eq_cast_eq-1(407; CHECK-NEXT:    [[X_SCALAR:%.*]] = bitcast <2 x i4> [[X:%.*]] to i8408; CHECK-NEXT:    [[Y_SCALAR:%.*]] = bitcast <2 x i4> [[Y:%.*]] to i8409; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X_SCALAR]], [[Y_SCALAR]]410; CHECK-NEXT:    ret i1 [[R]]411;412  %ic = icmp eq <2 x i4> %x, %y413  %b = bitcast <2 x i1> %ic to i2414  %r = icmp eq i2 %b, -1415  ret i1 %r416}417 418define i1 @ne_cast_eq-1(<3 x i7> %x, <3 x i7> %y) {419; CHECK-LABEL: @ne_cast_eq-1(420; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <3 x i7> [[X:%.*]], [[Y:%.*]]421; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <3 x i1> [[TMP1]] to i3422; CHECK-NEXT:    [[R:%.*]] = icmp eq i3 [[TMP2]], 0423; CHECK-NEXT:    ret i1 [[R]]424;425  %ic = icmp ne <3 x i7> %x, %y426  %b = bitcast <3 x i1> %ic to i3427  %r = icmp eq i3 %b, -1428  ret i1 %r429}430 431define i1 @eq_cast_ne-1(<2 x i7> %x, <2 x i7> %y) {432; CHECK-LABEL: @eq_cast_ne-1(433; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i7> [[X:%.*]], [[Y:%.*]]434; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i1> [[TMP1]] to i2435; CHECK-NEXT:    [[R:%.*]] = icmp ne i2 [[TMP2]], 0436; CHECK-NEXT:    ret i1 [[R]]437;438  %ic = icmp eq <2 x i7> %x, %y439  %b = bitcast <2 x i1> %ic to i2440  %r = icmp ne i2 %b, -1441  ret i1 %r442}443 444define i1 @eq_cast_ne-1-legal-scalar(<2 x i8> %x, <2 x i8> %y) {445; CHECK-LABEL: @eq_cast_ne-1-legal-scalar(446; CHECK-NEXT:    [[X_SCALAR:%.*]] = bitcast <2 x i8> [[X:%.*]] to i16447; CHECK-NEXT:    [[Y_SCALAR:%.*]] = bitcast <2 x i8> [[Y:%.*]] to i16448; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 [[X_SCALAR]], [[Y_SCALAR]]449; CHECK-NEXT:    ret i1 [[R]]450;451  %ic = icmp eq <2 x i8> %x, %y452  %b = bitcast <2 x i1> %ic to i2453  %r = icmp ne i2 %b, -1454  ret i1 %r455}456 457define i1 @ne_cast_ne-1(<3 x i5> %x, <3 x i5> %y) {458; CHECK-LABEL: @ne_cast_ne-1(459; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <3 x i5> [[X:%.*]], [[Y:%.*]]460; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <3 x i1> [[TMP1]] to i3461; CHECK-NEXT:    [[R:%.*]] = icmp ne i3 [[TMP2]], 0462; CHECK-NEXT:    ret i1 [[R]]463;464  %ic = icmp ne <3 x i5> %x, %y465  %b = bitcast <3 x i1> %ic to i3466  %r = icmp ne i3 %b, -1467  ret i1 %r468}469 470define i1 @ugt_cast_eq-1(<2 x i4> %x, <2 x i4> %y) {471; CHECK-LABEL: @ugt_cast_eq-1(472; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule <2 x i4> [[X:%.*]], [[Y:%.*]]473; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i1> [[TMP1]] to i2474; CHECK-NEXT:    [[R:%.*]] = icmp eq i2 [[TMP2]], 0475; CHECK-NEXT:    ret i1 [[R]]476;477  %ic = icmp ugt <2 x i4> %x, %y478  %b = bitcast <2 x i1> %ic to i2479  %r = icmp eq i2 %b, -1480  ret i1 %r481}482 483define i1 @slt_cast_ne-1(<2 x i4> %x, <2 x i4> %y) {484; CHECK-LABEL: @slt_cast_ne-1(485; CHECK-NEXT:    [[TMP1:%.*]] = icmp sge <2 x i4> [[X:%.*]], [[Y:%.*]]486; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i1> [[TMP1]] to i2487; CHECK-NEXT:    [[R:%.*]] = icmp ne i2 [[TMP2]], 0488; CHECK-NEXT:    ret i1 [[R]]489;490  %ic = icmp slt <2 x i4> %x, %y491  %b = bitcast <2 x i1> %ic to i2492  %r = icmp ne i2 %b, -1493  ret i1 %r494}495 496define i1 @ueq_cast_eq-1(<3 x float> %x, <3 x float> %y) {497; CHECK-LABEL: @ueq_cast_eq-1(498; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one <3 x float> [[X:%.*]], [[Y:%.*]]499; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <3 x i1> [[TMP1]] to i3500; CHECK-NEXT:    [[R:%.*]] = icmp eq i3 [[TMP2]], 0501; CHECK-NEXT:    ret i1 [[R]]502;503  %fc = fcmp ueq <3 x float> %x, %y504  %b = bitcast <3 x i1> %fc to i3505  %r = icmp eq i3 %b, -1506  ret i1 %r507}508 509define i1 @not_cast_ne-1(<3 x i1> %x) {510; CHECK-LABEL: @not_cast_ne-1(511; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <3 x i1> [[X:%.*]] to i3512; CHECK-NEXT:    [[R:%.*]] = icmp ne i3 [[TMP1]], 0513; CHECK-NEXT:    ret i1 [[R]]514;515  %not = xor <3 x i1> %x, <i1 -1, i1 -1, i1 -1>516  %b = bitcast <3 x i1> %not to i3517  %r = icmp ne i3 %b, -1518  ret i1 %r519}520 521define i1 @not_cast_ne-1_uses(<3 x i2> %x, ptr %p) {522; CHECK-LABEL: @not_cast_ne-1_uses(523; CHECK-NEXT:    [[NOT:%.*]] = xor <3 x i2> [[X:%.*]], splat (i2 -1)524; CHECK-NEXT:    store <3 x i2> [[NOT]], ptr [[P:%.*]], align 1525; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <3 x i2> [[X]] to i6526; CHECK-NEXT:    [[R:%.*]] = icmp ne i6 [[TMP1]], 0527; CHECK-NEXT:    ret i1 [[R]]528;529  %not = xor <3 x i2> %x, <i2 -1, i2 -1, i2 -1>530  store <3 x i2> %not, ptr %p531  %b = bitcast <3 x i2> %not to i6532  %r = icmp ne i6 %b, -1533  ret i1 %r534}535 536; negative test - need equality pred on 2nd cmp537 538define i1 @eq_cast_sgt-1(<3 x i4> %x, <3 x i4> %y) {539; CHECK-LABEL: @eq_cast_sgt-1(540; CHECK-NEXT:    [[IC:%.*]] = icmp eq <3 x i4> [[X:%.*]], [[Y:%.*]]541; CHECK-NEXT:    [[B:%.*]] = bitcast <3 x i1> [[IC]] to i3542; CHECK-NEXT:    [[R:%.*]] = icmp sgt i3 [[B]], -1543; CHECK-NEXT:    ret i1 [[R]]544;545  %ic = icmp eq <3 x i4> %x, %y546  %b = bitcast <3 x i1> %ic to i3547  %r = icmp sgt i3 %b, -1548  ret i1 %r549}550 551; negative test - need all-ones constant on 2nd cmp552 553define i1 @eq_cast_eq1(<2 x i4> %x, <2 x i4> %y) {554; CHECK-LABEL: @eq_cast_eq1(555; CHECK-NEXT:    [[IC:%.*]] = icmp eq <2 x i4> [[X:%.*]], [[Y:%.*]]556; CHECK-NEXT:    [[B:%.*]] = bitcast <2 x i1> [[IC]] to i2557; CHECK-NEXT:    [[R:%.*]] = icmp eq i2 [[B]], 1558; CHECK-NEXT:    ret i1 [[R]]559;560  %ic = icmp eq <2 x i4> %x, %y561  %b = bitcast <2 x i1> %ic to i2562  %r = icmp eq i2 %b, 1563  ret i1 %r564}565 566; negative test - extra use567 568define i1 @eq_cast_eq-1_use1(<2 x i4> %x, <2 x i4> %y, ptr %p) {569; CHECK-LABEL: @eq_cast_eq-1_use1(570; CHECK-NEXT:    [[IC:%.*]] = icmp sgt <2 x i4> [[X:%.*]], [[Y:%.*]]571; CHECK-NEXT:    store <2 x i1> [[IC]], ptr [[P:%.*]], align 1572; CHECK-NEXT:    [[B:%.*]] = bitcast <2 x i1> [[IC]] to i2573; CHECK-NEXT:    [[R:%.*]] = icmp eq i2 [[B]], -1574; CHECK-NEXT:    ret i1 [[R]]575;576  %ic = icmp sgt <2 x i4> %x, %y577  store <2 x i1> %ic, ptr %p578  %b = bitcast <2 x i1> %ic to i2579  %r = icmp eq i2 %b, -1580  ret i1 %r581}582 583; negative test - extra use584 585define i1 @eq_cast_eq-1_use2(<2 x i4> %x, <2 x i4> %y, ptr %p) {586; CHECK-LABEL: @eq_cast_eq-1_use2(587; CHECK-NEXT:    [[IC:%.*]] = icmp sgt <2 x i4> [[X:%.*]], [[Y:%.*]]588; CHECK-NEXT:    [[B:%.*]] = bitcast <2 x i1> [[IC]] to i2589; CHECK-NEXT:    store <2 x i1> [[IC]], ptr [[P:%.*]], align 1590; CHECK-NEXT:    [[R:%.*]] = icmp eq i2 [[B]], -1591; CHECK-NEXT:    ret i1 [[R]]592;593  %ic = icmp sgt <2 x i4> %x, %y594  %b = bitcast <2 x i1> %ic to i2595  store i2 %b, ptr %p596  %r = icmp eq i2 %b, -1597  ret i1 %r598}599 600define i1 @ne_cast_sext(<3 x i1> %b) {601; CHECK-LABEL: @ne_cast_sext(602; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <3 x i1> [[B:%.*]] to i3603; CHECK-NEXT:    [[R:%.*]] = icmp ne i3 [[TMP1]], 0604; CHECK-NEXT:    ret i1 [[R]]605;606  %e = sext <3 x i1> %b to <3 x i8>607  %bc = bitcast <3 x i8> %e to i24608  %r = icmp ne i24 %bc, 0609  ret i1 %r610}611 612define i1 @eq_cast_sext(<8 x i3> %b) {613; CHECK-LABEL: @eq_cast_sext(614; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <8 x i3> [[B:%.*]] to i24615; CHECK-NEXT:    [[R:%.*]] = icmp eq i24 [[TMP1]], 0616; CHECK-NEXT:    ret i1 [[R]]617;618  %e = sext <8 x i3> %b to <8 x i8>619  %bc = bitcast <8 x i8> %e to i64620  %r = icmp eq i64 %bc, 0621  ret i1 %r622}623 624define i1 @ne_cast_zext(<4 x i1> %b) {625; CHECK-LABEL: @ne_cast_zext(626; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i1> [[B:%.*]] to i4627; CHECK-NEXT:    [[R:%.*]] = icmp ne i4 [[TMP1]], 0628; CHECK-NEXT:    ret i1 [[R]]629;630  %e = zext <4 x i1> %b to <4 x i8>631  %bc = bitcast <4 x i8> %e to i32632  %r = icmp ne i32 %bc, 0633  ret i1 %r634}635 636define i1 @eq_cast_zext(<5 x i3> %b) {637; CHECK-LABEL: @eq_cast_zext(638; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <5 x i3> [[B:%.*]] to i15639; CHECK-NEXT:    [[R:%.*]] = icmp eq i15 [[TMP1]], 0640; CHECK-NEXT:    ret i1 [[R]]641;642  %e = zext <5 x i3> %b to <5 x i7>643  %bc = bitcast <5 x i7> %e to i35644  %r = icmp eq i35 %bc, 0645  ret i1 %r646}647 648; negative test - valid for eq/ne only649 650define i1 @sgt_cast_zext(<5 x i3> %b) {651; CHECK-LABEL: @sgt_cast_zext(652; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <5 x i3> [[B:%.*]] to i15653; CHECK-NEXT:    [[R:%.*]] = icmp ne i15 [[TMP1]], 0654; CHECK-NEXT:    ret i1 [[R]]655;656  %e = zext <5 x i3> %b to <5 x i7>657  %bc = bitcast <5 x i7> %e to i35658  %r = icmp sgt i35 %bc, 0659  ret i1 %r660}661 662; negative test - not valid with non-zero constants663; TODO: We could handle some non-zero constants by checking for bit-loss after casts.664 665define i1 @eq7_cast_sext(<5 x i3> %b) {666; CHECK-LABEL: @eq7_cast_sext(667; CHECK-NEXT:    [[E:%.*]] = sext <5 x i3> [[B:%.*]] to <5 x i7>668; CHECK-NEXT:    [[BC:%.*]] = bitcast <5 x i7> [[E]] to i35669; CHECK-NEXT:    [[R:%.*]] = icmp eq i35 [[BC]], 7670; CHECK-NEXT:    ret i1 [[R]]671;672  %e = sext <5 x i3> %b to <5 x i7>673  %bc = bitcast <5 x i7> %e to i35674  %r = icmp eq i35 %bc, 7675  ret i1 %r676}677 678; extra use of extend is ok679 680define i1 @eq_cast_zext_use1(<5 x i3> %b, ptr %p) {681; CHECK-LABEL: @eq_cast_zext_use1(682; CHECK-NEXT:    [[E:%.*]] = zext <5 x i3> [[B:%.*]] to <5 x i7>683; CHECK-NEXT:    store <5 x i7> [[E]], ptr [[P:%.*]], align 8684; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <5 x i3> [[B]] to i15685; CHECK-NEXT:    [[R:%.*]] = icmp eq i15 [[TMP1]], 0686; CHECK-NEXT:    ret i1 [[R]]687;688  %e = zext <5 x i3> %b to <5 x i7>689  store <5 x i7> %e, ptr %p690  %bc = bitcast <5 x i7> %e to i35691  %r = icmp eq i35 %bc, 0692  ret i1 %r693}694 695; negative test - don't create an extra cast696 697declare void @use35(i35)698 699define i1 @eq_cast_zext_use2(<5 x i3> %b) {700; CHECK-LABEL: @eq_cast_zext_use2(701; CHECK-NEXT:    [[E:%.*]] = zext <5 x i3> [[B:%.*]] to <5 x i7>702; CHECK-NEXT:    [[BC:%.*]] = bitcast <5 x i7> [[E]] to i35703; CHECK-NEXT:    call void @use35(i35 [[BC]])704; CHECK-NEXT:    [[R:%.*]] = icmp eq i35 [[BC]], 0705; CHECK-NEXT:    ret i1 [[R]]706;707  %e = zext <5 x i3> %b to <5 x i7>708  %bc = bitcast <5 x i7> %e to i35709  call void @use35(i35 %bc)710  %r = icmp eq i35 %bc, 0711  ret i1 %r712}713 714define i1 @eq_cast_eq_ptr-1(<2 x ptr> %x, <2 x ptr> %y) {715; CHECK-LABEL: @eq_cast_eq_ptr-1(716; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x ptr> [[X:%.*]], [[Y:%.*]]717; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i1> [[TMP1]] to i2718; CHECK-NEXT:    [[R:%.*]] = icmp eq i2 [[TMP2]], 0719; CHECK-NEXT:    ret i1 [[R]]720;721  %ic = icmp eq <2 x ptr> %x, %y722  %b = bitcast <2 x i1> %ic to i2723  %r = icmp eq i2 %b, -1724  ret i1 %r725}726 727define i1 @eq_cast_ne_ptr-1(<2 x ptr> %x, <2 x ptr> %y) {728; CHECK-LABEL: @eq_cast_ne_ptr-1(729; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x ptr> [[X:%.*]], [[Y:%.*]]730; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i1> [[TMP1]] to i2731; CHECK-NEXT:    [[R:%.*]] = icmp ne i2 [[TMP2]], 0732; CHECK-NEXT:    ret i1 [[R]]733;734  %ic = icmp eq <2 x ptr> %x, %y735  %b = bitcast <2 x i1> %ic to i2736  %r = icmp ne i2 %b, -1737  ret i1 %r738}739