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