108 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i8 %val)5 6; ucmp/scmp(x, y) >> N folds to either zext(x < y) or sext(x < y)7; if N is one less than the width of result of ucmp/scmp8define i8 @ucmp_to_zext(i32 %x, i32 %y) {9; CHECK-LABEL: define i8 @ucmp_to_zext(10; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {11; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X]], [[Y]]12; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i813; CHECK-NEXT: ret i8 [[TMP2]]14;15 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)16 %2 = lshr i8 %1, 717 ret i8 %218}19 20define i8 @ucmp_to_sext(i32 %x, i32 %y) {21; CHECK-LABEL: define i8 @ucmp_to_sext(22; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {23; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X]], [[Y]]24; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[TMP1]] to i825; CHECK-NEXT: ret i8 [[TMP2]]26;27 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)28 %2 = ashr i8 %1, 729 ret i8 %230}31 32define i8 @scmp_to_zext(i32 %x, i32 %y) {33; CHECK-LABEL: define i8 @scmp_to_zext(34; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {35; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], [[Y]]36; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i837; CHECK-NEXT: ret i8 [[TMP2]]38;39 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)40 %2 = lshr i8 %1, 741 ret i8 %242}43 44define i8 @scmp_to_sext(i32 %x, i32 %y) {45; CHECK-LABEL: define i8 @scmp_to_sext(46; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {47; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], [[Y]]48; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[TMP1]] to i849; CHECK-NEXT: ret i8 [[TMP2]]50;51 %1 = call i8 @llvm.scmp(i32 %x, i32 %y)52 %2 = ashr i8 %1, 753 ret i8 %254}55 56define <4 x i8> @scmp_to_sext_vec(<4 x i32> %x, <4 x i32> %y) {57; CHECK-LABEL: define <4 x i8> @scmp_to_sext_vec(58; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {59; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X]], [[Y]]60; CHECK-NEXT: [[TMP2:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i8>61; CHECK-NEXT: ret <4 x i8> [[TMP2]]62;63 %1 = call <4 x i8> @llvm.scmp(<4 x i32> %x, <4 x i32> %y)64 %2 = ashr <4 x i8> %1, <i8 7, i8 7, i8 7, i8 7>65 ret <4 x i8> %266}67 68; Negative test: incorrect shift amount69define i8 @ucmp_to_zext_neg1(i32 %x, i32 %y) {70; CHECK-LABEL: define i8 @ucmp_to_zext_neg1(71; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {72; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])73; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], 574; CHECK-NEXT: ret i8 [[TMP2]]75;76 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)77 %2 = lshr i8 %1, 578 ret i8 %279}80 81; Negative test: shift amount is not a constant82define i8 @ucmp_to_zext_neg2(i32 %x, i32 %y, i8 %s) {83; CHECK-LABEL: define i8 @ucmp_to_zext_neg2(84; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i8 [[S:%.*]]) {85; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])86; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[S]]87; CHECK-NEXT: ret i8 [[TMP2]]88;89 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)90 %2 = lshr i8 %1, %s91 ret i8 %292}93 94; Negative test: the result of ucmp/scmp is used more than once95define i8 @ucmp_to_zext_neg3(i32 %x, i32 %y) {96; CHECK-LABEL: define i8 @ucmp_to_zext_neg3(97; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {98; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])99; CHECK-NEXT: call void @use(i8 [[TMP1]])100; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], 7101; CHECK-NEXT: ret i8 [[TMP2]]102;103 %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)104 call void @use(i8 %1)105 %2 = lshr i8 %1, 7106 ret i8 %2107}108