brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.3 KiB · 13c7fce Raw
239 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.i1(i1 %x)5declare void @use.i64(i64 %x)6declare void @use.i64i1({i64, i1} %x)7 8define i1 @umul_greater_than_or_overflow_const(i64 %in) {9; CHECK-LABEL: define i1 @umul_greater_than_or_overflow_const(10; CHECK-SAME: i64 [[IN:%.*]]) {11; CHECK-NEXT:    [[TMP6:%.*]] = icmp ugt i64 [[IN]], 10980204805779495012; CHECK-NEXT:    ret i1 [[TMP6]]13;14  %mwo = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %in, i64 168)15  %mul = extractvalue { i64, i1 } %mwo, 016  %ovf = extractvalue { i64, i1 } %mwo, 117  %cmp = icmp ugt i64 %mul, -1618  %ret = or i1 %ovf, %cmp19  ret i1 %ret20}21 22define i1 @umul_greater_than_or_overflow_const_i8(i8 %in) {23; CHECK-LABEL: define i1 @umul_greater_than_or_overflow_const_i8(24; CHECK-SAME: i8 [[IN:%.*]]) {25; CHECK-NEXT:    [[TMP6:%.*]] = icmp ugt i8 [[IN]], 1026; CHECK-NEXT:    ret i1 [[TMP6]]27;28  %mwo = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %in, i8 24)29  %mul = extractvalue { i8, i1 } %mwo, 030  %ovf = extractvalue { i8, i1 } %mwo, 131  %cmp = icmp ugt i8 %mul, -1632  %ret = or i1 %ovf, %cmp33  ret i1 %ret34}35 36define i1 @umul_greater_than_or_overflow_const_commuted(i64 %in) {37; CHECK-LABEL: define i1 @umul_greater_than_or_overflow_const_commuted(38; CHECK-SAME: i64 [[IN:%.*]]) {39; CHECK-NEXT:    [[TMP6:%.*]] = icmp ugt i64 [[IN]], 19215358410114116240; CHECK-NEXT:    ret i1 [[TMP6]]41;42  %mwo = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %in, i64 48)43  %mul = extractvalue { i64, i1 } %mwo, 044  %ovf = extractvalue { i64, i1 } %mwo, 145  %cmp = icmp ugt i64 %mul, 922337203685477580046  %ret = or i1 %cmp, %ovf47  ret i1 %ret48}49 50define i1 @umul_greater_than_or_overflow_const_disjoint(i64 %in) {51; CHECK-LABEL: define i1 @umul_greater_than_or_overflow_const_disjoint(52; CHECK-SAME: i64 [[IN:%.*]]) {53; CHECK-NEXT:    [[TMP6:%.*]] = icmp ugt i64 [[IN]], 23058430092136939554; CHECK-NEXT:    ret i1 [[TMP6]]55;56  %mwo = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %in, i64 40)57  %mul = extractvalue { i64, i1 } %mwo, 058  %ovf = extractvalue { i64, i1 } %mwo, 159  %cmp = icmp ugt i64 %mul, 922337203685477580060  %ret = or disjoint i1 %ovf, %cmp61  ret i1 %ret62}63 64define i1 @umul_greater_than_or_overflow_const_multiuse_mul(i64 %in) {65; CHECK-LABEL: define i1 @umul_greater_than_or_overflow_const_multiuse_mul(66; CHECK-SAME: i64 [[IN:%.*]]) {67; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[IN]], 4868; CHECK-NEXT:    [[RET:%.*]] = icmp ugt i64 [[IN]], 19215358410114116269; CHECK-NEXT:    tail call void @use.i64(i64 [[MUL]])70; CHECK-NEXT:    ret i1 [[RET]]71;72  %mwo = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %in, i64 48)73  %mul = extractvalue { i64, i1 } %mwo, 074  %ovf = extractvalue { i64, i1 } %mwo, 175  %cmp = icmp ugt i64 %mul, 922337203685477580076  %ret = or i1 %ovf, %cmp77  tail call void @use.i64(i64 %mul)78  ret i1 %ret79}80 81define i1 @umul_greater_than_or_overflow_const_multiuse_overflow(i64 %in) {82; CHECK-LABEL: define i1 @umul_greater_than_or_overflow_const_multiuse_overflow(83; CHECK-SAME: i64 [[IN:%.*]]) {84; CHECK-NEXT:    [[OVF:%.*]] = icmp ugt i64 [[IN]], 38430716820228232585; CHECK-NEXT:    [[RET:%.*]] = icmp ugt i64 [[IN]], 19215358410114116286; CHECK-NEXT:    tail call void @use.i1(i1 [[OVF]])87; CHECK-NEXT:    ret i1 [[RET]]88;89  %mwo = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %in, i64 48)90  %mul = extractvalue { i64, i1 } %mwo, 091  %ovf = extractvalue { i64, i1 } %mwo, 192  %cmp = icmp ugt i64 %mul, 922337203685477580093  %ret = or i1 %ovf, %cmp94  tail call void @use.i1(i1 %ovf)95  ret i1 %ret96}97 98define i1 @umul_greater_than_or_overflow_const_multiuse_umul_call(i64 %in) {99; CHECK-LABEL: define i1 @umul_greater_than_or_overflow_const_multiuse_umul_call(100; CHECK-SAME: i64 [[IN:%.*]]) {101; CHECK-NEXT:    [[MWO:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[IN]], i64 48)102; CHECK-NEXT:    [[RET:%.*]] = icmp ugt i64 [[IN]], 192153584101141162103; CHECK-NEXT:    tail call void @use.i64i1({ i64, i1 } [[MWO]])104; CHECK-NEXT:    ret i1 [[RET]]105;106  %mwo = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %in, i64 48)107  %mul = extractvalue { i64, i1 } %mwo, 0108  %ovf = extractvalue { i64, i1 } %mwo, 1109  %cmp = icmp ugt i64 %mul, 9223372036854775800110  %ret = or i1 %ovf, %cmp111  tail call void @use.i64i1({ i64, i1 } %mwo)112  ret i1 %ret113}114 115define <2 x i1> @umul_greater_than_or_overflow_const_vector_splat(<2 x i64> %in) {116; CHECK-LABEL: define <2 x i1> @umul_greater_than_or_overflow_const_vector_splat(117; CHECK-SAME: <2 x i64> [[IN:%.*]]) {118; CHECK-NEXT:    [[TMP6:%.*]] = icmp ugt <2 x i64> [[IN]], splat (i64 6477087104532848)119; CHECK-NEXT:    ret <2 x i1> [[TMP6]]120;121  %mwo = tail call { <2 x i64>, <2 x i1> } @llvm.umul.with.overflow.v2i64(<2 x i64> %in, <2 x i64> <i64 1424, i64 1424>)122  %mul = extractvalue { <2 x i64>, <2 x i1> } %mwo, 0123  %ovf = extractvalue { <2 x i64>, <2 x i1> } %mwo, 1124  %cmp = icmp ugt <2 x i64> %mul, <i64 9223372036854775800, i64 9223372036854775800>125  %ret = or <2 x i1> %ovf, %cmp126  ret <2 x i1> %ret127}128 129; Negative test130define <4 x i1> @umul_greater_than_or_overflow_const_vector_non_splat_negative(<4 x i64> %in) {131; CHECK-LABEL: define <4 x i1> @umul_greater_than_or_overflow_const_vector_non_splat_negative(132; CHECK-SAME: <4 x i64> [[IN:%.*]]) {133; CHECK-NEXT:    [[MWO:%.*]] = tail call { <4 x i64>, <4 x i1> } @llvm.umul.with.overflow.v4i64(<4 x i64> [[IN]], <4 x i64> <i64 24, i64 1424, i64 0, i64 -1>)134; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { <4 x i64>, <4 x i1> } [[MWO]], 0135; CHECK-NEXT:    [[OVF:%.*]] = extractvalue { <4 x i64>, <4 x i1> } [[MWO]], 1136; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <4 x i64> [[MUL]], <i64 9223372036854775000, i64 9223372036854775800, i64 -16, i64 -16>137; CHECK-NEXT:    [[RET:%.*]] = or <4 x i1> [[OVF]], [[CMP]]138; CHECK-NEXT:    ret <4 x i1> [[RET]]139;140  %mwo = tail call { <4 x i64>, <4 x i1> } @llvm.umul.with.overflow.v2i64(<4 x i64> %in, <4 x i64> <i64 24, i64 1424, i64 0, i64 -1>)141  %mul = extractvalue { <4 x i64>, <4 x i1> } %mwo, 0142  %ovf = extractvalue { <4 x i64>, <4 x i1> } %mwo, 1143  %cmp = icmp ugt <4 x i64> %mul, <i64 9223372036854775000, i64 9223372036854775800, i64 -16, i64 -16>144  %ret = or <4 x i1> %ovf, %cmp145  ret <4 x i1> %ret146}147 148; Negative test149define <2 x i1> @umul_greater_than_or_overflow_const_vector_poison_non_splat_negative(<2 x i64> %in) {150; CHECK-LABEL: define <2 x i1> @umul_greater_than_or_overflow_const_vector_poison_non_splat_negative(151; CHECK-SAME: <2 x i64> [[IN:%.*]]) {152; CHECK-NEXT:    [[MWO:%.*]] = tail call { <2 x i64>, <2 x i1> } @llvm.umul.with.overflow.v2i64(<2 x i64> [[IN]], <2 x i64> <i64 poison, i64 1424>)153; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { <2 x i64>, <2 x i1> } [[MWO]], 0154; CHECK-NEXT:    [[OVF:%.*]] = extractvalue { <2 x i64>, <2 x i1> } [[MWO]], 1155; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i64> [[MUL]], <i64 9223372036854775800, i64 poison>156; CHECK-NEXT:    [[RET:%.*]] = or <2 x i1> [[OVF]], [[CMP]]157; CHECK-NEXT:    ret <2 x i1> [[RET]]158;159  %mwo = tail call { <2 x i64>, <2 x i1> } @llvm.umul.with.overflow.v2i64(<2 x i64> %in, <2 x i64> <i64 poison, i64 1424>)160  %mul = extractvalue { <2 x i64>, <2 x i1> } %mwo, 0161  %ovf = extractvalue { <2 x i64>, <2 x i1> } %mwo, 1162  %cmp = icmp ugt <2 x i64> %mul, <i64 9223372036854775800, i64 poison>163  %ret = or <2 x i1> %ovf, %cmp164  ret <2 x i1> %ret165}166 167; Negative test168define i1 @umul_greater_than_and_overflow_const_negative(i64 %in) {169; CHECK-LABEL: define i1 @umul_greater_than_and_overflow_const_negative(170; CHECK-SAME: i64 [[IN:%.*]]) {171; CHECK-NEXT:    [[TMP2:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[IN]], i64 48)172; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP2]], 0173; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1174; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i64 [[TMP3]], 9223372036854775800175; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP4]], [[TMP5]]176; CHECK-NEXT:    ret i1 [[TMP6]]177;178  %mwo = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %in, i64 48)179  %mul = extractvalue { i64, i1 } %mwo, 0180  %ovf = extractvalue { i64, i1 } %mwo, 1181  %cmp = icmp ult i64 %mul, 9223372036854775800182  %ret = and i1 %ovf, %cmp183  ret i1 %ret184}185 186; Negative test187define i1 @umul_less_than_or_overflow_const_negative(i64 %in) {188; CHECK-LABEL: define i1 @umul_less_than_or_overflow_const_negative(189; CHECK-SAME: i64 [[IN:%.*]]) {190; CHECK-NEXT:    [[TMP2:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[IN]], i64 48)191; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP2]], 0192; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1193; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i64 [[TMP3]], 9223372036854775800194; CHECK-NEXT:    [[TMP6:%.*]] = or i1 [[TMP4]], [[TMP5]]195; CHECK-NEXT:    ret i1 [[TMP6]]196;197  %mwo = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %in, i64 48)198  %mul = extractvalue { i64, i1 } %mwo, 0199  %ovf = extractvalue { i64, i1 } %mwo, 1200  %cmp = icmp ult i64 %mul, 9223372036854775800201  %ret = or i1 %ovf, %cmp202  ret i1 %ret203}204 205; Negative test206define i1 @umul_greater_than_or_overflow_const_multiuse_icmp_negative(i64 %in) {207; CHECK-LABEL: define i1 @umul_greater_than_or_overflow_const_multiuse_icmp_negative(208; CHECK-SAME: i64 [[IN:%.*]]) {209; CHECK-NEXT:    [[TMP2:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[IN]], i64 48)210; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP2]], 0211; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1212; CHECK-NEXT:    [[TMP5:%.*]] = icmp ugt i64 [[TMP3]], 9223372036854775800213; CHECK-NEXT:    [[TMP6:%.*]] = or i1 [[TMP4]], [[TMP5]]214; CHECK-NEXT:    tail call void @use.i1(i1 [[TMP5]])215; CHECK-NEXT:    ret i1 [[TMP6]]216;217  %mwo = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %in, i64 48)218  %mul = extractvalue { i64, i1 } %mwo, 0219  %ovf = extractvalue { i64, i1 } %mwo, 1220  %cmp = icmp ugt i64 %mul, 9223372036854775800221  %ret = or i1 %ovf, %cmp222  tail call void @use.i1(i1 %cmp)223  ret i1 %ret224}225 226; Negative test. The umul.with.overflow should be folded away before.227define i1 @umul_greater_than_or_overflow_const_0_negative(i64 %in) {228; CHECK-LABEL: define i1 @umul_greater_than_or_overflow_const_0_negative(229; CHECK-SAME: i64 [[IN:%.*]]) {230; CHECK-NEXT:    ret i1 false231;232  %mwo = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %in, i64 0)233  %mul = extractvalue { i64, i1 } %mwo, 0234  %ovf = extractvalue { i64, i1 } %mwo, 1235  %cmp = icmp ugt i64 %mul, 0236  %ret = or i1 %ovf, %cmp237  ret i1 %ret238}239