1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define <2 x i1> @sub_XY_and_bit0_is_zero(<2 x i8> %x, <2 x i8> %C) nounwind { 5; CHECK-LABEL: @sub_XY_and_bit0_is_zero( 6; CHECK-NEXT: ret <2 x i1> zeroinitializer 7; 8 %C1 = or <2 x i8> %C, <i8 9, i8 9> 9 %y = sub <2 x i8> %x, %C1 10 %w = and <2 x i8> %x, %y 11 %r = icmp eq <2 x i8> %w, <i8 -1, i8 -1> 12 ret <2 x i1> %r 13} 14 15define i1 @sub_XY_xor_bit0_is_one(i8 %x, i8 %C) nounwind { 16; CHECK-LABEL: @sub_XY_xor_bit0_is_one( 17; CHECK-NEXT: ret i1 false 18; 19 %C1 = or i8 %C, 1 20 %y = sub i8 %x, %C1 21 %w = xor i8 %x, %y 22 %r = icmp eq i8 %w, 10 23 ret i1 %r 24} 25 26define i1 @sub_XY_or_bit0_is_one(i8 %x, i8 %C) nounwind { 27; CHECK-LABEL: @sub_XY_or_bit0_is_one( 28; CHECK-NEXT: ret i1 false 29; 30 %C1 = or i8 %C, 1 31 %y = sub i8 %x, %C1 32 %w = or i8 %x, %y 33 %r = icmp eq i8 %w, 10 34 ret i1 %r 35} 36 37define i1 @sub_YX_and_bit0_is_zero(i8 %x, i8 %C) nounwind { 38; CHECK-LABEL: @sub_YX_and_bit0_is_zero( 39; CHECK-NEXT: ret i1 false 40; 41 %C1 = or i8 %C, 1 42 %y = sub i8 %C1, %x 43 %w = and i8 %x, %y 44 %r = icmp eq i8 %w, -1 45 ret i1 %r 46} 47 48define <2 x i1> @sub_YX_xor_bit0_is_one(<2 x i8> %x, <2 x i8> %C) nounwind { 49; CHECK-LABEL: @sub_YX_xor_bit0_is_one( 50; CHECK-NEXT: ret <2 x i1> zeroinitializer 51; 52 %C1 = or <2 x i8> %C, <i8 1, i8 1> 53 %y = sub <2 x i8> %C1, %x 54 %w = xor <2 x i8> %x, %y 55 %r = icmp eq <2 x i8> %w, <i8 12, i8 12> 56 ret <2 x i1> %r 57} 58 59define i1 @sub_YX_or_bit0_is_one(i8 %x, i8 %C) nounwind { 60; CHECK-LABEL: @sub_YX_or_bit0_is_one( 61; CHECK-NEXT: ret i1 false 62; 63 %C1 = or i8 %C, 1 64 %y = sub i8 %C1, %x 65 %w = or i8 %x, %y 66 %r = icmp eq i8 %w, 32 67 ret i1 %r 68} 69 70define i1 @add_YX_xor_bit0_is_one(i8 %x, i8 %C) nounwind { 71; CHECK-LABEL: @add_YX_xor_bit0_is_one( 72; CHECK-NEXT: ret i1 false 73; 74 %C1 = or i8 %C, 1 75 %y = add i8 %C1, %x 76 %w = xor i8 %x, %y 77 %r = icmp eq i8 %w, 32 78 ret i1 %r 79} 80 81define <2 x i1> @add_XY_or_bit0_is_one(<2 x i8> %x, <2 x i8> %C) nounwind { 82; CHECK-LABEL: @add_XY_or_bit0_is_one( 83; CHECK-NEXT: ret <2 x i1> zeroinitializer 84; 85 %C1 = or <2 x i8> %C, <i8 1, i8 1> 86 %y = add <2 x i8> %C1, %x 87 %w = or <2 x i8> %x, %y 88 %r = icmp eq <2 x i8> %w, <i8 90, i8 90> 89 ret <2 x i1> %r 90} 91 92define <2 x i1> @sub_XY_and_bit0_is_zero_fail(<2 x i8> %x, <2 x i8> %C) nounwind { 93; CHECK-LABEL: @sub_XY_and_bit0_is_zero_fail( 94; CHECK-NEXT: [[C1:%.*]] = or <2 x i8> [[C:%.*]], splat (i8 8) 95; CHECK-NEXT: [[Y:%.*]] = sub <2 x i8> [[X:%.*]], [[C1]] 96; CHECK-NEXT: [[W:%.*]] = and <2 x i8> [[X]], [[Y]] 97; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[W]], splat (i8 -1) 98; CHECK-NEXT: ret <2 x i1> [[R]] 99; 100 %C1 = or <2 x i8> %C, <i8 8, i8 8> 101 %y = sub <2 x i8> %x, %C1 102 %w = and <2 x i8> %x, %y 103 %r = icmp eq <2 x i8> %w, <i8 -1, i8 -1> 104 ret <2 x i1> %r 105} 106 107define i1 @sub_XY_xor_bit0_is_one_fail(i8 %x, i8 %C) nounwind { 108; CHECK-LABEL: @sub_XY_xor_bit0_is_one_fail( 109; CHECK-NEXT: [[C1:%.*]] = xor i8 [[C:%.*]], 1 110; CHECK-NEXT: [[Y:%.*]] = sub i8 [[X:%.*]], [[C1]] 111; CHECK-NEXT: [[W:%.*]] = xor i8 [[X]], [[Y]] 112; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[W]], 10 113; CHECK-NEXT: ret i1 [[R]] 114; 115 %C1 = xor i8 %C, 1 116 %y = sub i8 %x, %C1 117 %w = xor i8 %x, %y 118 %r = icmp eq i8 %w, 10 119 ret i1 %r 120} 121 122define i1 @sub_XY_or_bit0_is_one_fail(i8 %x, i8 %C) nounwind { 123; CHECK-LABEL: @sub_XY_or_bit0_is_one_fail( 124; CHECK-NEXT: [[Y:%.*]] = sub i8 [[X:%.*]], [[C:%.*]] 125; CHECK-NEXT: [[W:%.*]] = or i8 [[X]], [[Y]] 126; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[W]], 10 127; CHECK-NEXT: ret i1 [[R]] 128; 129 %y = sub i8 %x, %C 130 %w = or i8 %x, %y 131 %r = icmp eq i8 %w, 10 132 ret i1 %r 133} 134 135define i1 @sub_YX_and_bit0_is_zero_fail(i8 %x, i8 %C) nounwind { 136; CHECK-LABEL: @sub_YX_and_bit0_is_zero_fail( 137; CHECK-NEXT: [[Y:%.*]] = sub i8 [[C:%.*]], [[X:%.*]] 138; CHECK-NEXT: [[W:%.*]] = and i8 [[X]], [[Y]] 139; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[W]], -1 140; CHECK-NEXT: ret i1 [[R]] 141; 142 %y = sub i8 %C, %x 143 %w = and i8 %x, %y 144 %r = icmp eq i8 %w, -1 145 ret i1 %r 146} 147 148define <2 x i1> @sub_YX_xor_bit0_is_one_fail(<2 x i8> %x, <2 x i8> %C) nounwind { 149; CHECK-LABEL: @sub_YX_xor_bit0_is_one_fail( 150; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i8> [[X:%.*]], [[C:%.*]] 151; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i8> [[X]], [[TMP1]] 152; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[TMP2]], splat (i8 -13) 153; CHECK-NEXT: ret <2 x i1> [[R]] 154; 155 %C1 = sub <2 x i8> %C, <i8 1, i8 1> 156 %y = sub <2 x i8> %C1, %x 157 %w = xor <2 x i8> %x, %y 158 %r = icmp eq <2 x i8> %w, <i8 12, i8 12> 159 ret <2 x i1> %r 160} 161 162define i1 @sub_YX_or_bit0_is_one_fail(i8 %x, i8 %C) nounwind { 163; CHECK-LABEL: @sub_YX_or_bit0_is_one_fail( 164; CHECK-NEXT: [[C1:%.*]] = xor i8 [[C:%.*]], 1 165; CHECK-NEXT: [[Y:%.*]] = sub i8 [[C1]], [[X:%.*]] 166; CHECK-NEXT: [[W:%.*]] = or i8 [[X]], [[Y]] 167; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[W]], 32 168; CHECK-NEXT: ret i1 [[R]] 169; 170 %C1 = xor i8 %C, 1 171 %y = sub i8 %C1, %x 172 %w = or i8 %x, %y 173 %r = icmp eq i8 %w, 32 174 ret i1 %r 175} 176 177define i1 @add_YX_xor_bit0_is_one_fail(i8 %x, i8 %C) nounwind { 178; CHECK-LABEL: @add_YX_xor_bit0_is_one_fail( 179; CHECK-NEXT: [[C1:%.*]] = and i8 [[C:%.*]], 1 180; CHECK-NEXT: [[Y:%.*]] = add i8 [[C1]], [[X:%.*]] 181; CHECK-NEXT: [[W:%.*]] = xor i8 [[X]], [[Y]] 182; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[W]], 32 183; CHECK-NEXT: ret i1 [[R]] 184; 185 %C1 = and i8 %C, 1 186 %y = add i8 %C1, %x 187 %w = xor i8 %x, %y 188 %r = icmp eq i8 %w, 32 189 ret i1 %r 190} 191 192define <2 x i1> @add_XY_or_bit0_is_one_fail(<2 x i8> %x, <2 x i8> %C) nounwind { 193; CHECK-LABEL: @add_XY_or_bit0_is_one_fail( 194; CHECK-NEXT: [[C1:%.*]] = add <2 x i8> [[C:%.*]], splat (i8 1) 195; CHECK-NEXT: [[Y:%.*]] = add <2 x i8> [[C1]], [[X:%.*]] 196; CHECK-NEXT: [[W:%.*]] = or <2 x i8> [[X]], [[Y]] 197; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[W]], splat (i8 90) 198; CHECK-NEXT: ret <2 x i1> [[R]] 199; 200 %C1 = add <2 x i8> %C, <i8 1, i8 1> 201 %y = add <2 x i8> %C1, %x 202 %w = or <2 x i8> %x, %y 203 %r = icmp eq <2 x i8> %w, <i8 90, i8 90> 204 ret <2 x i1> %r 205} 206 207;; These tests are just to check if it can simplify using demanded bits path. 208define <2 x i32> @add_and_eval_vec(<2 x i32> %x, <2 x i32> %C) { 209; CHECK-LABEL: @add_and_eval_vec( 210; CHECK-NEXT: ret <2 x i32> zeroinitializer 211; 212 %y = add <2 x i32> %x, <i32 1, i32 1> 213 %z = and <2 x i32> %x, %y 214 ;; shl so we don't commute the and 215 %b = shl <2 x i32> %z, <i32 31, i32 31> 216 ret <2 x i32> %b 217} 218 219 220define <2 x i32> @add_xor_eval_vec(<2 x i32> %x) { 221; CHECK-LABEL: @add_xor_eval_vec( 222; CHECK-NEXT: ret <2 x i32> splat (i32 1) 223; 224 %y = add <2 x i32> %x, <i32 1, i32 1> 225 %z = xor <2 x i32> %y, %x 226 %b = and <2 x i32> %z, <i32 1, i32 1> 227 ret <2 x i32> %b 228} 229 230define <2 x i32> @add_or_eval_vec(<2 x i32> %x, <2 x i32> %C) { 231; CHECK-LABEL: @add_or_eval_vec( 232; CHECK-NEXT: ret <2 x i32> splat (i32 1) 233; 234 %y = add <2 x i32> %x, <i32 1, i32 1> 235 %z = or <2 x i32> %y, %x 236 %b = and <2 x i32> %z, <i32 1, i32 1> 237 ret <2 x i32> %b 238} 239