1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; https://bugs.llvm.org/show_bug.cgi?id=38123 5 6; Pattern: 7; x & (-1 >> y) != x 8; Should be transformed into: 9; x u> (-1 >> y) 10 11; ============================================================================ ; 12; Basic positive tests 13; ============================================================================ ; 14 15define i1 @p0(i8 %x, i8 %y) { 16; CHECK-LABEL: @p0( 17; CHECK-NEXT: [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]] 18; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[TMP0]], [[X:%.*]] 19; CHECK-NEXT: ret i1 [[TMP1]] 20; 21 %tmp0 = lshr i8 -1, %y 22 %tmp1 = and i8 %tmp0, %x 23 %ret = icmp ne i8 %tmp1, %x 24 ret i1 %ret 25} 26 27; ============================================================================ ; 28; Vector tests 29; ============================================================================ ; 30 31define <2 x i1> @p1_vec(<2 x i8> %x, <2 x i8> %y) { 32; CHECK-LABEL: @p1_vec( 33; CHECK-NEXT: [[TMP0:%.*]] = lshr <2 x i8> <i8 -1, i8 -1>, [[Y:%.*]] 34; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i8> [[TMP0]], [[X:%.*]] 35; CHECK-NEXT: ret <2 x i1> [[TMP1]] 36; 37 %tmp0 = lshr <2 x i8> <i8 -1, i8 -1>, %y 38 %tmp1 = and <2 x i8> %tmp0, %x 39 %ret = icmp ne <2 x i8> %tmp1, %x 40 ret <2 x i1> %ret 41} 42 43define <3 x i1> @p2_vec_undef(<3 x i8> %x, <3 x i8> %y) { 44; CHECK-LABEL: @p2_vec_undef( 45; CHECK-NEXT: [[TMP0:%.*]] = lshr <3 x i8> <i8 -1, i8 undef, i8 -1>, [[Y:%.*]] 46; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <3 x i8> [[TMP0]], [[X:%.*]] 47; CHECK-NEXT: ret <3 x i1> [[TMP1]] 48; 49 %tmp0 = lshr <3 x i8> <i8 -1, i8 undef, i8 -1>, %y 50 %tmp1 = and <3 x i8> %tmp0, %x 51 %ret = icmp ne <3 x i8> %tmp1, %x 52 ret <3 x i1> %ret 53} 54 55; ============================================================================ ; 56; Commutativity tests. 57; ============================================================================ ; 58 59declare i8 @gen8() 60 61define i1 @c0(i8 %y) { 62; CHECK-LABEL: @c0( 63; CHECK-NEXT: [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]] 64; CHECK-NEXT: [[X:%.*]] = call i8 @gen8() 65; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X]], [[TMP0]] 66; CHECK-NEXT: ret i1 [[TMP1]] 67; 68 %tmp0 = lshr i8 -1, %y 69 %x = call i8 @gen8() 70 %tmp1 = and i8 %x, %tmp0 ; swapped order 71 %ret = icmp ne i8 %tmp1, %x 72 ret i1 %ret 73} 74 75define i1 @c1(i8 %y) { 76; CHECK-LABEL: @c1( 77; CHECK-NEXT: [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]] 78; CHECK-NEXT: [[X:%.*]] = call i8 @gen8() 79; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X]], [[TMP0]] 80; CHECK-NEXT: ret i1 [[TMP1]] 81; 82 %tmp0 = lshr i8 -1, %y 83 %x = call i8 @gen8() 84 %tmp1 = and i8 %tmp0, %x 85 %ret = icmp ne i8 %x, %tmp1 ; swapped order 86 ret i1 %ret 87} 88 89define i1 @c2(i8 %y) { 90; CHECK-LABEL: @c2( 91; CHECK-NEXT: [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]] 92; CHECK-NEXT: [[X:%.*]] = call i8 @gen8() 93; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X]], [[TMP0]] 94; CHECK-NEXT: ret i1 [[TMP1]] 95; 96 %tmp0 = lshr i8 -1, %y 97 %x = call i8 @gen8() 98 %tmp1 = and i8 %x, %tmp0 ; swapped order 99 %ret = icmp ne i8 %x, %tmp1 ; swapped order 100 ret i1 %ret 101} 102 103; ============================================================================ ; 104; One-use tests. We don't care about multi-uses here. 105; ============================================================================ ; 106 107declare void @use8(i8) 108 109define i1 @oneuse0(i8 %x, i8 %y) { 110; CHECK-LABEL: @oneuse0( 111; CHECK-NEXT: [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]] 112; CHECK-NEXT: call void @use8(i8 [[TMP0]]) 113; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[TMP0]], [[X:%.*]] 114; CHECK-NEXT: ret i1 [[TMP1]] 115; 116 %tmp0 = lshr i8 -1, %y 117 call void @use8(i8 %tmp0) 118 %tmp1 = and i8 %tmp0, %x 119 %ret = icmp ne i8 %tmp1, %x 120 ret i1 %ret 121} 122 123define i1 @oneuse1(i8 %x, i8 %y) { 124; CHECK-LABEL: @oneuse1( 125; CHECK-NEXT: [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]] 126; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[TMP0]], [[X:%.*]] 127; CHECK-NEXT: call void @use8(i8 [[TMP1]]) 128; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[TMP0]], [[X]] 129; CHECK-NEXT: ret i1 [[TMP1]] 130; 131 %tmp0 = lshr i8 -1, %y 132 %tmp1 = and i8 %tmp0, %x 133 call void @use8(i8 %tmp1) 134 %ret = icmp ne i8 %tmp1, %x 135 ret i1 %ret 136} 137 138define i1 @oneuse2(i8 %x, i8 %y) { 139; CHECK-LABEL: @oneuse2( 140; CHECK-NEXT: [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]] 141; CHECK-NEXT: call void @use8(i8 [[TMP0]]) 142; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[TMP0]], [[X:%.*]] 143; CHECK-NEXT: call void @use8(i8 [[TMP1]]) 144; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[TMP0]], [[X]] 145; CHECK-NEXT: ret i1 [[TMP1]] 146; 147 %tmp0 = lshr i8 -1, %y 148 call void @use8(i8 %tmp0) 149 %tmp1 = and i8 %tmp0, %x 150 call void @use8(i8 %tmp1) 151 %ret = icmp ne i8 %tmp1, %x 152 ret i1 %ret 153} 154 155; ============================================================================ ; 156; Negative tests 157; ============================================================================ ; 158 159define i1 @n0(i8 %x, i8 %y, i8 %notx) { 160; CHECK-LABEL: @n0( 161; CHECK-NEXT: [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]] 162; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[TMP0]], [[X:%.*]] 163; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], [[NOTX:%.*]] 164; CHECK-NEXT: ret i1 [[RET]] 165; 166 %tmp0 = lshr i8 -1, %y 167 %tmp1 = and i8 %tmp0, %x 168 %ret = icmp ne i8 %tmp1, %notx ; not %x 169 ret i1 %ret 170} 171