1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; Tests to verify proper functioning of the icmp folding implemented in 5; InstCombiner::foldICmpBitCastConstant 6; Specifically, folding: 7; icmp <pred> iN X, C 8; where X = bitcast <M x iK> (shufflevector <M x iK> %vec, undef, SC)) to iN 9; and C is a splat of a K-bit pattern 10; and SC is a constant vector = <C', C', C', ..., C'> 11; Into: 12; %E = extractelement <M x iK> %vec, i32 C' 13; icmp <pred> iK %E, trunc(C) 14 15define i1 @test_i1_0(i1 %val) { 16; CHECK-LABEL: @test_i1_0( 17; CHECK-NEXT: [[COND:%.*]] = xor i1 [[VAL:%.*]], true 18; CHECK-NEXT: ret i1 [[COND]] 19; 20 %insvec = insertelement <4 x i1> undef, i1 %val, i32 0 21 %vec = shufflevector <4 x i1> %insvec, <4 x i1> undef, <4 x i32> zeroinitializer 22 %cast = bitcast <4 x i1> %vec to i4 23 %cond = icmp eq i4 %cast, 0 24 ret i1 %cond 25} 26 27define i1 @test_i1_0_2(i1 %val) { 28; CHECK-LABEL: @test_i1_0_2( 29; CHECK-NEXT: [[COND:%.*]] = xor i1 [[VAL:%.*]], true 30; CHECK-NEXT: ret i1 [[COND]] 31; 32 %insvec = insertelement <4 x i1> undef, i1 %val, i32 2 33 %vec = shufflevector <4 x i1> %insvec, <4 x i1> undef, <4 x i32> <i32 2, i32 2, i32 2, i32 2> 34 %cast = bitcast <4 x i1> %vec to i4 35 %cond = icmp eq i4 %cast, 0 36 ret i1 %cond 37} 38 39define i1 @test_i1_m1(i1 %val) { 40; CHECK-LABEL: @test_i1_m1( 41; CHECK-NEXT: ret i1 [[VAL:%.*]] 42; 43 %insvec = insertelement <4 x i1> undef, i1 %val, i32 0 44 %vec = shufflevector <4 x i1> %insvec, <4 x i1> undef, <4 x i32> zeroinitializer 45 %cast = bitcast <4 x i1> %vec to i4 46 %cond = icmp eq i4 %cast, -1 47 ret i1 %cond 48} 49 50define i1 @test_i8_pattern(i8 %val) { 51; CHECK-LABEL: @test_i8_pattern( 52; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[VAL:%.*]], 72 53; CHECK-NEXT: ret i1 [[COND]] 54; 55 %insvec = insertelement <4 x i8> undef, i8 %val, i32 0 56 %vec = shufflevector <4 x i8> %insvec, <4 x i8> undef, <4 x i32> zeroinitializer 57 %cast = bitcast <4 x i8> %vec to i32 58 %cond = icmp eq i32 %cast, 1212696648 59 ret i1 %cond 60} 61 62define i1 @test_i8_pattern_2(i8 %val) { 63; CHECK-LABEL: @test_i8_pattern_2( 64; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[VAL:%.*]], 72 65; CHECK-NEXT: ret i1 [[COND]] 66; 67 %insvec = insertelement <4 x i8> undef, i8 %val, i32 2 68 %vec = shufflevector <4 x i8> %insvec, <4 x i8> undef, <4 x i32> <i32 2, i32 2, i32 2, i32 2> 69 %cast = bitcast <4 x i8> %vec to i32 70 %cond = icmp eq i32 %cast, 1212696648 71 ret i1 %cond 72} 73 74; Make sure we don't try to fold if the shufflemask has differing element values 75define i1 @test_i8_pattern_3(<4 x i8> %invec) { 76; CHECK-LABEL: @test_i8_pattern_3( 77; CHECK-NEXT: [[VEC:%.*]] = shufflevector <4 x i8> [[INVEC:%.*]], <4 x i8> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2> 78; CHECK-NEXT: [[CAST:%.*]] = bitcast <4 x i8> [[VEC]] to i32 79; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[CAST]], 1212696648 80; CHECK-NEXT: ret i1 [[COND]] 81; 82 %vec = shufflevector <4 x i8> %invec, <4 x i8> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2> 83 %cast = bitcast <4 x i8> %vec to i32 84 %cond = icmp eq i32 %cast, 1212696648 85 ret i1 %cond 86} 87 88; Make sure we don't try to fold if the compared-to constant isn't a splatted value 89define i1 @test_i8_nopattern(i8 %val) { 90; CHECK-LABEL: @test_i8_nopattern( 91; CHECK-NEXT: [[INSVEC:%.*]] = insertelement <4 x i8> undef, i8 [[VAL:%.*]], i32 0 92; CHECK-NEXT: [[VEC:%.*]] = shufflevector <4 x i8> [[INSVEC]], <4 x i8> undef, <4 x i32> zeroinitializer 93; CHECK-NEXT: [[CAST:%.*]] = bitcast <4 x i8> [[VEC]] to i32 94; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[CAST]], 1212696647 95; CHECK-NEXT: ret i1 [[COND]] 96; 97 %insvec = insertelement <4 x i8> undef, i8 %val, i32 0 98 %vec = shufflevector <4 x i8> %insvec, <4 x i8> undef, <4 x i32> zeroinitializer 99 %cast = bitcast <4 x i8> %vec to i32 100 %cond = icmp eq i32 %cast, 1212696647 101 ret i1 %cond 102} 103 104; Verify that we fold more than just the eq predicate 105define i1 @test_i8_ult_pattern(i8 %val) { 106; CHECK-LABEL: @test_i8_ult_pattern( 107; CHECK-NEXT: [[COND:%.*]] = icmp ult i8 [[VAL:%.*]], 72 108; CHECK-NEXT: ret i1 [[COND]] 109; 110 %insvec = insertelement <4 x i8> undef, i8 %val, i32 0 111 %vec = shufflevector <4 x i8> %insvec, <4 x i8> undef, <4 x i32> zeroinitializer 112 %cast = bitcast <4 x i8> %vec to i32 113 %cond = icmp ult i32 %cast, 1212696648 114 ret i1 %cond 115} 116 117define i1 @extending_shuffle_with_weird_types(<2 x i9> %v) { 118; CHECK-LABEL: @extending_shuffle_with_weird_types( 119; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x i9> [[V:%.*]], i32 0 120; CHECK-NEXT: [[CMP:%.*]] = icmp slt i9 [[TMP1]], 1 121; CHECK-NEXT: ret i1 [[CMP]] 122; 123 %splat = shufflevector <2 x i9> %v, <2 x i9> undef, <3 x i32> zeroinitializer 124 %cast = bitcast <3 x i9> %splat to i27 125 %cmp = icmp slt i27 %cast, 262657 ; 0x040201 126 ret i1 %cmp 127} 128