1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4define i8 @scmp_lt() { 5; CHECK-LABEL: define i8 @scmp_lt() { 6; CHECK-NEXT: ret i8 -1 7; 8 %1 = call i8 @llvm.scmp(i32 -7, i32 3) 9 ret i8 %1 10} 11 12define i8 @scmp_eq() { 13; CHECK-LABEL: define i8 @scmp_eq() { 14; CHECK-NEXT: ret i8 0 15; 16 %1 = call i8 @llvm.scmp(i32 2, i32 2) 17 ret i8 %1 18} 19 20define i8 @scmp_gt() { 21; CHECK-LABEL: define i8 @scmp_gt() { 22; CHECK-NEXT: ret i8 1 23; 24 %1 = call i8 @llvm.scmp(i32 2, i32 -7) 25 ret i8 %1 26} 27 28define i8 @ucmp_lt() { 29; CHECK-LABEL: define i8 @ucmp_lt() { 30; CHECK-NEXT: ret i8 -1 31; 32 %1 = call i8 @llvm.ucmp(i32 7, i32 12) 33 ret i8 %1 34} 35 36define i2 @ucmp_eq() { 37; CHECK-LABEL: define i2 @ucmp_eq() { 38; CHECK-NEXT: ret i2 0 39; 40 %1 = call i2 @llvm.ucmp(i32 12, i32 12) 41 ret i2 %1 42} 43 44define i100 @ucmp_gt() { 45; CHECK-LABEL: define i100 @ucmp_gt() { 46; CHECK-NEXT: ret i100 1 47; 48 %1 = call i100 @llvm.ucmp(i32 7, i32 3) 49 ret i100 %1 50} 51 52define i8 @ucmp_poison() { 53; CHECK-LABEL: define i8 @ucmp_poison() { 54; CHECK-NEXT: ret i8 poison 55; 56 %1 = call i8 @llvm.ucmp(i32 poison, i32 5) 57 ret i8 %1 58} 59 60define i8 @scmp_poison() { 61; CHECK-LABEL: define i8 @scmp_poison() { 62; CHECK-NEXT: ret i8 poison 63; 64 %1 = call i8 @llvm.scmp(i32 0, i32 poison) 65 ret i8 %1 66} 67 68define i8 @scmp_undef() { 69; CHECK-LABEL: define i8 @scmp_undef() { 70; CHECK-NEXT: ret i8 0 71; 72 %1 = call i8 @llvm.scmp(i32 undef, i32 -12) 73 ret i8 %1 74} 75 76define i8 @ucmp_undef() { 77; CHECK-LABEL: define i8 @ucmp_undef() { 78; CHECK-NEXT: ret i8 0 79; 80 %1 = call i8 @llvm.ucmp(i32 2, i32 undef) 81 ret i8 %1 82} 83 84define <4 x i8> @ucmp_lt_splat() { 85; CHECK-LABEL: define <4 x i8> @ucmp_lt_splat() { 86; CHECK-NEXT: ret <4 x i8> splat (i8 -1) 87; 88 %1 = call <4 x i8> @llvm.ucmp(<4 x i32> splat(i32 1), <4 x i32> splat(i32 3)) 89 ret <4 x i8> %1 90} 91 92define <4 x i8> @scmp_nonsplat() { 93; CHECK-LABEL: define <4 x i8> @scmp_nonsplat() { 94; CHECK-NEXT: ret <4 x i8> <i8 1, i8 0, i8 1, i8 -1> 95; 96 %1 = call <4 x i8> @llvm.scmp(<4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32> <i32 -1, i32 1, i32 -2, i32 4>) 97 ret <4 x i8> %1 98} 99 100define i8 @scmp_with_itself(i32 %x) { 101; CHECK-LABEL: define i8 @scmp_with_itself( 102; CHECK-SAME: i32 [[X:%.*]]) { 103; CHECK-NEXT: ret i8 0 104; 105 %1 = call i8 @llvm.scmp(i32 %x, i32 %x) 106 ret i8 %1 107} 108 109define <4 x i8> @ucmp_vec_with_itself(<4 x i32> %x) { 110; CHECK-LABEL: define <4 x i8> @ucmp_vec_with_itself( 111; CHECK-SAME: <4 x i32> [[X:%.*]]) { 112; CHECK-NEXT: ret <4 x i8> zeroinitializer 113; 114 %1 = call <4 x i8> @llvm.scmp(<4 x i32> %x, <4 x i32> %x) 115 ret <4 x i8> %1 116} 117 118define i8 @scmp_known_gt(i32 %x, i32 %y) { 119; CHECK-LABEL: define i8 @scmp_known_gt( 120; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 121; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X]], [[Y]] 122; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) 123; CHECK-NEXT: ret i8 1 124; 125 %1 = icmp sgt i32 %x, %y 126 call void @llvm.assume(i1 %1) 127 128 %2 = call i8 @llvm.scmp(i32 %x, i32 %y) 129 ret i8 %2 130} 131 132define i8 @scmp_known_eq(i32 %x, i32 %y) { 133; CHECK-LABEL: define i8 @scmp_known_eq( 134; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 135; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], [[Y]] 136; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) 137; CHECK-NEXT: ret i8 0 138; 139 %1 = icmp eq i32 %x, %y 140 call void @llvm.assume(i1 %1) 141 142 %2 = call i8 @llvm.scmp(i32 %x, i32 %y) 143 ret i8 %2 144} 145 146define i8 @scmp_known_lt(i32 %x, i32 %y) { 147; CHECK-LABEL: define i8 @scmp_known_lt( 148; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 149; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], [[Y]] 150; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) 151; CHECK-NEXT: ret i8 -1 152; 153 %1 = icmp slt i32 %x, %y 154 call void @llvm.assume(i1 %1) 155 156 %2 = call i8 @llvm.scmp(i32 %x, i32 %y) 157 ret i8 %2 158} 159 160define i8 @ucmp_known_gt(i32 %x, i32 %y) { 161; CHECK-LABEL: define i8 @ucmp_known_gt( 162; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 163; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X]], [[Y]] 164; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) 165; CHECK-NEXT: ret i8 1 166; 167 %1 = icmp ugt i32 %x, %y 168 call void @llvm.assume(i1 %1) 169 170 %2 = call i8 @llvm.ucmp(i32 %x, i32 %y) 171 ret i8 %2 172} 173 174define i8 @ucmp_known_eq(i32 %x, i32 %y) { 175; CHECK-LABEL: define i8 @ucmp_known_eq( 176; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 177; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], [[Y]] 178; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) 179; CHECK-NEXT: ret i8 0 180; 181 %1 = icmp eq i32 %x, %y 182 call void @llvm.assume(i1 %1) 183 184 %2 = call i8 @llvm.ucmp(i32 %x, i32 %y) 185 ret i8 %2 186} 187 188define i8 @ucmp_known_lt(i32 %x, i32 %y) { 189; CHECK-LABEL: define i8 @ucmp_known_lt( 190; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 191; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X]], [[Y]] 192; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) 193; CHECK-NEXT: ret i8 -1 194; 195 %1 = icmp ult i32 %x, %y 196 call void @llvm.assume(i1 %1) 197 198 %2 = call i8 @llvm.ucmp(i32 %x, i32 %y) 199 ret i8 %2 200} 201 202define i8 @ucmp_with_addition(i32 %x) { 203; CHECK-LABEL: define i8 @ucmp_with_addition( 204; CHECK-SAME: i32 [[X:%.*]]) { 205; CHECK-NEXT: ret i8 -1 206; 207 %1 = add nuw i32 %x, 1 208 %2 = call i8 @llvm.ucmp(i32 %x, i32 %1) 209 ret i8 %2 210} 211 212define i8 @ucmp_with_addition2(i32 %x) { 213; CHECK-LABEL: define i8 @ucmp_with_addition2( 214; CHECK-SAME: i32 [[X:%.*]]) { 215; CHECK-NEXT: ret i8 1 216; 217 %1 = add nuw i32 %x, 1 218 %2 = call i8 @llvm.ucmp(i32 %1, i32 %x) 219 ret i8 %2 220} 221 222define <4 x i8> @ucmp_with_addition_vec(<4 x i32> %x) { 223; CHECK-LABEL: define <4 x i8> @ucmp_with_addition_vec( 224; CHECK-SAME: <4 x i32> [[X:%.*]]) { 225; CHECK-NEXT: ret <4 x i8> splat (i8 -1) 226; 227 %1 = add nuw <4 x i32> %x, splat(i32 1) 228 %2 = call <4 x i8> @llvm.ucmp(<4 x i32> %x, <4 x i32> %1) 229 ret <4 x i8> %2 230} 231 232define i1 @scmp_eq_4(i32 %x, i32 %y) { 233; CHECK-LABEL: define i1 @scmp_eq_4( 234; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 235; CHECK-NEXT: ret i1 false 236; 237 %1 = call i8 @llvm.scmp(i32 %x, i32 %y) 238 %2 = icmp eq i8 %1, 4 239 ret i1 %2 240} 241 242define i1 @ucmp_ne_negative_2(i32 %x, i32 %y) { 243; CHECK-LABEL: define i1 @ucmp_ne_negative_2( 244; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 245; CHECK-NEXT: ret i1 true 246; 247 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y) 248 %2 = icmp ne i8 %1, -2 249 ret i1 %2 250} 251 252; Negative case: mismatched signedness of predicates 253define i8 @scmp_known_ugt(i32 %x, i32 %y) { 254; CHECK-LABEL: define i8 @scmp_known_ugt( 255; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 256; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X]], [[Y]] 257; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) 258; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]]) 259; CHECK-NEXT: ret i8 [[TMP2]] 260; 261 %1 = icmp ugt i32 %x, %y 262 call void @llvm.assume(i1 %1) 263 264 %2 = call i8 @llvm.scmp(i32 %x, i32 %y) 265 ret i8 %2 266} 267 268define i8 @scmp_known_ult(i32 %x, i32 %y) { 269; CHECK-LABEL: define i8 @scmp_known_ult( 270; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 271; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X]], [[Y]] 272; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) 273; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]]) 274; CHECK-NEXT: ret i8 [[TMP2]] 275; 276 %1 = icmp ult i32 %x, %y 277 call void @llvm.assume(i1 %1) 278 279 %2 = call i8 @llvm.scmp(i32 %x, i32 %y) 280 ret i8 %2 281} 282 283define i8 @ucmp_known_sgt(i32 %x, i32 %y) { 284; CHECK-LABEL: define i8 @ucmp_known_sgt( 285; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 286; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X]], [[Y]] 287; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) 288; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]]) 289; CHECK-NEXT: ret i8 [[TMP2]] 290; 291 %1 = icmp sgt i32 %x, %y 292 call void @llvm.assume(i1 %1) 293 294 %2 = call i8 @llvm.ucmp(i32 %x, i32 %y) 295 ret i8 %2 296} 297 298define i8 @ucmp_known_slt(i32 %x, i32 %y) { 299; CHECK-LABEL: define i8 @ucmp_known_slt( 300; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 301; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], [[Y]] 302; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) 303; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]]) 304; CHECK-NEXT: ret i8 [[TMP2]] 305; 306 %1 = icmp slt i32 %x, %y 307 call void @llvm.assume(i1 %1) 308 309 %2 = call i8 @llvm.ucmp(i32 %x, i32 %y) 310 ret i8 %2 311} 312 313; Negative case: no nuw flag 314define i8 @ucmp_with_addition_no_nuw(i32 %x) { 315; CHECK-LABEL: define i8 @ucmp_with_addition_no_nuw( 316; CHECK-SAME: i32 [[X:%.*]]) { 317; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 1 318; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[TMP1]]) 319; CHECK-NEXT: ret i8 [[TMP2]] 320; 321 %1 = add i32 %x, 1 322 %2 = call i8 @llvm.ucmp(i32 %x, i32 %1) 323 ret i8 %2 324} 325