brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.5 KiB · 2e80148 Raw
276 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)5declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)6declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)7declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)8 9declare void @use(i1)10 11; Tests from PR7536012define i1 @ckd_add_unsigned(i31 %num) {13; CHECK-LABEL: define i1 @ckd_add_unsigned(14; CHECK-SAME: i31 [[NUM:%.*]]) {15; CHECK-NEXT:    [[A2:%.*]] = icmp eq i31 [[NUM]], -116; CHECK-NEXT:    ret i1 [[A2]]17;18  %a0 = zext i31 %num to i3219  %a1 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a0, i32 1)20  %a2 = extractvalue { i32, i1 } %a1, 121  %a3 = extractvalue { i32, i1 } %a1, 022  %a4 = icmp slt i32 %a3, 023  %a5 = or i1 %a2, %a424  ret i1 %a525}26 27define i1 @ckd_add_unsigned_commuted(i31 %num) {28; CHECK-LABEL: define i1 @ckd_add_unsigned_commuted(29; CHECK-SAME: i31 [[NUM:%.*]]) {30; CHECK-NEXT:    [[A2:%.*]] = icmp eq i31 [[NUM]], -131; CHECK-NEXT:    ret i1 [[A2]]32;33  %a0 = zext i31 %num to i3234  %a1 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a0, i32 1)35  %a2 = extractvalue { i32, i1 } %a1, 136  %a3 = extractvalue { i32, i1 } %a1, 037  %a4 = icmp slt i32 %a3, 038  %a5 = or i1 %a4, %a239  ret i1 %a540}41 42define i1 @ckd_add_unsigned_imply_true(i31 %num) {43; CHECK-LABEL: define i1 @ckd_add_unsigned_imply_true(44; CHECK-SAME: i31 [[NUM:%.*]]) {45; CHECK-NEXT:    ret i1 true46;47  %a0 = zext i31 %num to i3248  %a1 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a0, i32 1)49  %a2 = extractvalue { i32, i1 } %a1, 150  %a3 = extractvalue { i32, i1 } %a1, 051  %a4 = icmp sgt i32 %a3, -152  %a5 = or i1 %a2, %a453  ret i1 %a554}55 56define i1 @canonicalize_or_sadd_with_overflow_icmp(i32 %a0) {57; CHECK-LABEL: define i1 @canonicalize_or_sadd_with_overflow_icmp(58; CHECK-SAME: i32 [[A0:%.*]]) {59; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A0]], -214748364760; CHECK-NEXT:    [[A5:%.*]] = icmp sgt i32 [[TMP1]], -161; CHECK-NEXT:    ret i1 [[A5]]62;63  %a1 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a0, i32 1)64  %a2 = extractvalue { i32, i1 } %a1, 165  %a3 = extractvalue { i32, i1 } %a1, 066  %a4 = icmp slt i32 %a3, 067  %a5 = or i1 %a2, %a468  ret i1 %a569}70 71define i1 @canonicalize_or_ssub_with_overflow_icmp(i32 %a0) {72; CHECK-LABEL: define i1 @canonicalize_or_ssub_with_overflow_icmp(73; CHECK-SAME: i32 [[A0:%.*]]) {74; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[A0]], 175; CHECK-NEXT:    ret i1 [[TMP1]]76;77  %a1 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a0, i32 1)78  %a2 = extractvalue { i32, i1 } %a1, 179  %a3 = extractvalue { i32, i1 } %a1, 080  %a4 = icmp slt i32 %a3, 081  %a5 = or i1 %a2, %a482  ret i1 %a583}84 85define i1 @canonicalize_or_uadd_with_overflow_icmp(i32 %a0) {86; CHECK-LABEL: define i1 @canonicalize_or_uadd_with_overflow_icmp(87; CHECK-SAME: i32 [[A0:%.*]]) {88; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A0]], 189; CHECK-NEXT:    [[A5:%.*]] = icmp ult i32 [[TMP1]], 1090; CHECK-NEXT:    ret i1 [[A5]]91;92  %a1 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a0, i32 1)93  %a2 = extractvalue { i32, i1 } %a1, 194  %a3 = extractvalue { i32, i1 } %a1, 095  %a4 = icmp ult i32 %a3, 1096  %a5 = or i1 %a2, %a497  ret i1 %a598}99 100define i1 @canonicalize_or_sadd_with_overflow_icmp_eq(i32 %a0) {101; CHECK-LABEL: define i1 @canonicalize_or_sadd_with_overflow_icmp_eq(102; CHECK-SAME: i32 [[A0:%.*]]) {103; CHECK-NEXT:    [[A2:%.*]] = icmp eq i32 [[A0]], 2147483647104; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A0]], 9105; CHECK-NEXT:    [[A5:%.*]] = or i1 [[A2]], [[TMP1]]106; CHECK-NEXT:    ret i1 [[A5]]107;108  %a1 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a0, i32 1)109  %a2 = extractvalue { i32, i1 } %a1, 1110  %a3 = extractvalue { i32, i1 } %a1, 0111  %a4 = icmp eq i32 %a3, 10112  %a5 = or i1 %a2, %a4113  ret i1 %a5114}115 116define i1 @canonicalize_or_uadd_with_overflow_icmp_ne(i32 %a0) {117; CHECK-LABEL: define i1 @canonicalize_or_uadd_with_overflow_icmp_ne(118; CHECK-SAME: i32 [[A0:%.*]]) {119; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[A0]], 9120; CHECK-NEXT:    ret i1 [[TMP1]]121;122  %a1 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a0, i32 1)123  %a2 = extractvalue { i32, i1 } %a1, 1124  %a3 = extractvalue { i32, i1 } %a1, 0125  %a4 = icmp ne i32 %a3, 10126  %a5 = or i1 %a2, %a4127  ret i1 %a5128}129 130; Negative tests131define i1 @canonicalize_or_sadd_with_overflow_icmp_mismatched_pred(i32 %a0) {132; CHECK-LABEL: define i1 @canonicalize_or_sadd_with_overflow_icmp_mismatched_pred(133; CHECK-SAME: i32 [[A0:%.*]]) {134; CHECK-NEXT:    [[A1:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A0]], i32 1)135; CHECK-NEXT:    [[A2:%.*]] = extractvalue { i32, i1 } [[A1]], 1136; CHECK-NEXT:    [[A3:%.*]] = extractvalue { i32, i1 } [[A1]], 0137; CHECK-NEXT:    [[A4:%.*]] = icmp ult i32 [[A3]], 2138; CHECK-NEXT:    [[A5:%.*]] = or i1 [[A2]], [[A4]]139; CHECK-NEXT:    ret i1 [[A5]]140;141  %a1 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a0, i32 1)142  %a2 = extractvalue { i32, i1 } %a1, 1143  %a3 = extractvalue { i32, i1 } %a1, 0144  %a4 = icmp ult i32 %a3, 2145  %a5 = or i1 %a2, %a4146  ret i1 %a5147}148 149define i1 @canonicalize_or_sadd_with_overflow_icmp_non_constant1(i32 %a0, i32 %c) {150; CHECK-LABEL: define i1 @canonicalize_or_sadd_with_overflow_icmp_non_constant1(151; CHECK-SAME: i32 [[A0:%.*]], i32 [[C:%.*]]) {152; CHECK-NEXT:    [[A1:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A0]], i32 [[C]])153; CHECK-NEXT:    [[A2:%.*]] = extractvalue { i32, i1 } [[A1]], 1154; CHECK-NEXT:    [[A3:%.*]] = extractvalue { i32, i1 } [[A1]], 0155; CHECK-NEXT:    [[A4:%.*]] = icmp slt i32 [[A3]], 0156; CHECK-NEXT:    [[A5:%.*]] = or i1 [[A2]], [[A4]]157; CHECK-NEXT:    ret i1 [[A5]]158;159  %a1 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a0, i32 %c)160  %a2 = extractvalue { i32, i1 } %a1, 1161  %a3 = extractvalue { i32, i1 } %a1, 0162  %a4 = icmp slt i32 %a3, 0163  %a5 = or i1 %a2, %a4164  ret i1 %a5165}166 167define i1 @canonicalize_or_sadd_with_overflow_icmp_non_constant2(i32 %a0, i32 %c) {168; CHECK-LABEL: define i1 @canonicalize_or_sadd_with_overflow_icmp_non_constant2(169; CHECK-SAME: i32 [[A0:%.*]], i32 [[C:%.*]]) {170; CHECK-NEXT:    [[A1:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A0]], i32 1)171; CHECK-NEXT:    [[A2:%.*]] = extractvalue { i32, i1 } [[A1]], 1172; CHECK-NEXT:    [[A3:%.*]] = extractvalue { i32, i1 } [[A1]], 0173; CHECK-NEXT:    [[A4:%.*]] = icmp slt i32 [[A3]], [[C]]174; CHECK-NEXT:    [[A5:%.*]] = or i1 [[A2]], [[A4]]175; CHECK-NEXT:    ret i1 [[A5]]176;177  %a1 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a0, i32 1)178  %a2 = extractvalue { i32, i1 } %a1, 1179  %a3 = extractvalue { i32, i1 } %a1, 0180  %a4 = icmp slt i32 %a3, %c181  %a5 = or i1 %a2, %a4182  ret i1 %a5183}184 185define i1 @canonicalize_or_sadd_with_overflow_icmp_multiuse(i32 %a0) {186; CHECK-LABEL: define i1 @canonicalize_or_sadd_with_overflow_icmp_multiuse(187; CHECK-SAME: i32 [[A0:%.*]]) {188; CHECK-NEXT:    [[A1:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A0]], i32 1)189; CHECK-NEXT:    [[A2:%.*]] = extractvalue { i32, i1 } [[A1]], 1190; CHECK-NEXT:    [[A3:%.*]] = extractvalue { i32, i1 } [[A1]], 0191; CHECK-NEXT:    [[A4:%.*]] = icmp slt i32 [[A3]], 0192; CHECK-NEXT:    call void @use(i1 [[A4]])193; CHECK-NEXT:    [[A5:%.*]] = or i1 [[A2]], [[A4]]194; CHECK-NEXT:    ret i1 [[A5]]195;196  %a1 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a0, i32 1)197  %a2 = extractvalue { i32, i1 } %a1, 1198  %a3 = extractvalue { i32, i1 } %a1, 0199  %a4 = icmp slt i32 %a3, 0200  call void @use(i1 %a4)201  %a5 = or i1 %a2, %a4202  ret i1 %a5203}204 205define i1 @canonicalize_or_sadd_with_overflow_icmp_overflow(i32 %a0) {206; CHECK-LABEL: define i1 @canonicalize_or_sadd_with_overflow_icmp_overflow(207; CHECK-SAME: i32 [[A0:%.*]]) {208; CHECK-NEXT:    [[A1:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A0]], i32 -2147483647)209; CHECK-NEXT:    [[A2:%.*]] = extractvalue { i32, i1 } [[A1]], 1210; CHECK-NEXT:    [[A3:%.*]] = extractvalue { i32, i1 } [[A1]], 0211; CHECK-NEXT:    [[A4:%.*]] = icmp slt i32 [[A3]], 2212; CHECK-NEXT:    [[A5:%.*]] = or i1 [[A2]], [[A4]]213; CHECK-NEXT:    ret i1 [[A5]]214;215  %a1 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a0, i32 -2147483647)216  %a2 = extractvalue { i32, i1 } %a1, 1217  %a3 = extractvalue { i32, i1 } %a1, 0218  %a4 = icmp slt i32 %a3, 2219  %a5 = or i1 %a2, %a4220  ret i1 %a5221}222 223define i1 @canonicalize_or_uadd_with_overflow_icmp_overflow(i32 %a0) {224; CHECK-LABEL: define i1 @canonicalize_or_uadd_with_overflow_icmp_overflow(225; CHECK-SAME: i32 [[A0:%.*]]) {226; CHECK-NEXT:    [[A1:%.*]] = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[A0]], i32 3)227; CHECK-NEXT:    [[A2:%.*]] = extractvalue { i32, i1 } [[A1]], 1228; CHECK-NEXT:    [[A3:%.*]] = extractvalue { i32, i1 } [[A1]], 0229; CHECK-NEXT:    [[A4:%.*]] = icmp ult i32 [[A3]], 2230; CHECK-NEXT:    [[A5:%.*]] = or i1 [[A2]], [[A4]]231; CHECK-NEXT:    ret i1 [[A5]]232;233  %a1 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a0, i32 3)234  %a2 = extractvalue { i32, i1 } %a1, 1235  %a3 = extractvalue { i32, i1 } %a1, 0236  %a4 = icmp ult i32 %a3, 2237  %a5 = or i1 %a2, %a4238  ret i1 %a5239}240 241define i1 @canonicalize_or_ssub_with_overflow_icmp_overflow(i32 %a0) {242; CHECK-LABEL: define i1 @canonicalize_or_ssub_with_overflow_icmp_overflow(243; CHECK-SAME: i32 [[A0:%.*]]) {244; CHECK-NEXT:    [[A1:%.*]] = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[A0]], i32 -2147483648)245; CHECK-NEXT:    [[A2:%.*]] = extractvalue { i32, i1 } [[A1]], 1246; CHECK-NEXT:    [[A3:%.*]] = extractvalue { i32, i1 } [[A1]], 0247; CHECK-NEXT:    [[A4:%.*]] = icmp slt i32 [[A3]], -1248; CHECK-NEXT:    [[A5:%.*]] = or i1 [[A2]], [[A4]]249; CHECK-NEXT:    ret i1 [[A5]]250;251  %a1 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a0, i32 -2147483648)252  %a2 = extractvalue { i32, i1 } %a1, 1253  %a3 = extractvalue { i32, i1 } %a1, 0254  %a4 = icmp slt i32 %a3, -1255  %a5 = or i1 %a2, %a4256  ret i1 %a5257}258 259define i1 @canonicalize_or_smul_with_overflow_icmp(i32 %a0) {260; CHECK-LABEL: define i1 @canonicalize_or_smul_with_overflow_icmp(261; CHECK-SAME: i32 [[A0:%.*]]) {262; CHECK-NEXT:    [[A1:%.*]] = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[A0]], i32 3)263; CHECK-NEXT:    [[A2:%.*]] = extractvalue { i32, i1 } [[A1]], 1264; CHECK-NEXT:    [[A3:%.*]] = extractvalue { i32, i1 } [[A1]], 0265; CHECK-NEXT:    [[A4:%.*]] = icmp slt i32 [[A3]], 10266; CHECK-NEXT:    [[A5:%.*]] = or i1 [[A2]], [[A4]]267; CHECK-NEXT:    ret i1 [[A5]]268;269  %a1 = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %a0, i32 3)270  %a2 = extractvalue { i32, i1 } %a1, 1271  %a3 = extractvalue { i32, i1 } %a1, 0272  %a4 = icmp slt i32 %a3, 10273  %a5 = or i1 %a2, %a4274  ret i1 %a5275}276