354 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52 3; RUN: opt -S -passes=instcombine < %s | FileCheck %s4 5; When C0 is neither 0 nor 1:6; umax(nuw_mul(x, C0), x + 1) is optimized to:7; x == 0 ? 1 : nuw_mul(x, C0)8; When C0 is not 0:9; umax(nuw_shl(x, C0), x + 1) is optimized to:10; x == 0 ? 1 : nuw_shl(x, C0)11 12; Positive Test Cases for `shl`13 14define i64 @test_shl_by_2(i64 %x) {15; CHECK-LABEL: define i64 @test_shl_by_2(16; CHECK-SAME: i64 [[X:%.*]]) {17; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[X]], 218; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 019; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[TMP2]]20; CHECK-NEXT: ret i64 [[MAX]]21;22 %x1 = add i64 %x, 123 %shl = shl nuw i64 %x, 224 %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)25 ret i64 %max26}27 28define i64 @test_shl_by_5(i64 %x) {29; CHECK-LABEL: define i64 @test_shl_by_5(30; CHECK-SAME: i64 [[X:%.*]]) {31; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[X]], 532; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 033; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[TMP2]]34; CHECK-NEXT: ret i64 [[MAX]]35;36 %x1 = add i64 %x, 137 %shl = shl nuw i64 %x, 538 %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)39 ret i64 %max40}41 42define i64 @test_shl_with_nsw(i64 %x) {43; CHECK-LABEL: define i64 @test_shl_with_nsw(44; CHECK-SAME: i64 [[X:%.*]]) {45; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i64 [[X]], 246; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 047; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[SHL]]48; CHECK-NEXT: ret i64 [[MAX]]49;50 %x1 = add i64 %x, 151 %shl = shl nuw nsw i64 %x, 252 %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)53 ret i64 %max54}55 56define <2 x i64> @test_shl_vector_by_2(<2 x i64> %x) {57; CHECK-LABEL: define <2 x i64> @test_shl_vector_by_2(58; CHECK-SAME: <2 x i64> [[X:%.*]]) {59; CHECK-NEXT: [[SHL:%.*]] = shl nuw <2 x i64> [[X]], splat (i64 2)60; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X]], zeroinitializer61; CHECK-NEXT: [[MAX:%.*]] = select <2 x i1> [[TMP1]], <2 x i64> splat (i64 1), <2 x i64> [[SHL]]62; CHECK-NEXT: ret <2 x i64> [[MAX]]63;64 %x1 = add <2 x i64> %x, <i64 1, i64 1>65 %shl = shl nuw <2 x i64> %x, <i64 2, i64 2>66 %max = call <2 x i64> @llvm.umax.v2i64(<2 x i64> %shl, <2 x i64> %x1)67 ret <2 x i64> %max68}69 70; Commuted Test Cases for `shl`71 72define i64 @test_shl_umax_commuted(i64 %x) {73; CHECK-LABEL: define i64 @test_shl_umax_commuted(74; CHECK-SAME: i64 [[X:%.*]]) {75; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[X]], 276; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 077; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[SHL]]78; CHECK-NEXT: ret i64 [[MAX]]79;80 %x1 = add i64 %x, 181 %shl = shl nuw i64 %x, 282 %max = call i64 @llvm.umax.i64(i64 %x1, i64 %shl)83 ret i64 %max84}85 86; Negative Test Cases for `shl`87 88define i64 @test_shl_by_zero(i64 %x) {89; CHECK-LABEL: define i64 @test_shl_by_zero(90; CHECK-SAME: i64 [[X:%.*]]) {91; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 192; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[X]], i64 [[X1]])93; CHECK-NEXT: ret i64 [[MAX]]94;95 %x1 = add i64 %x, 196 %shl = shl nuw i64 %x, 097 %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)98 ret i64 %max99}100 101define i64 @test_shl_add_by_2(i64 %x) {102; CHECK-LABEL: define i64 @test_shl_add_by_2(103; CHECK-SAME: i64 [[X:%.*]]) {104; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 2105; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[X]], 2106; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])107; CHECK-NEXT: ret i64 [[MAX]]108;109 %x1 = add i64 %x, 2110 %shl = shl nuw i64 %x, 2111 %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)112 ret i64 %max113}114 115define i64 @test_shl_without_nuw(i64 %x) {116; CHECK-LABEL: define i64 @test_shl_without_nuw(117; CHECK-SAME: i64 [[X:%.*]]) {118; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1119; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[X]], 2120; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])121; CHECK-NEXT: ret i64 [[MAX]]122;123 %x1 = add i64 %x, 1124 %shl = shl i64 %x, 2125 %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)126 ret i64 %max127}128 129define i64 @test_shl_umin(i64 %x) {130; CHECK-LABEL: define i64 @test_shl_umin(131; CHECK-SAME: i64 [[X:%.*]]) {132; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1133; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[X]], 2134; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umin.i64(i64 [[SHL]], i64 [[X1]])135; CHECK-NEXT: ret i64 [[MAX]]136;137 %x1 = add i64 %x, 1138 %shl = shl nuw i64 %x, 2139 %max = call i64 @llvm.umin.i64(i64 %shl, i64 %x1)140 ret i64 %max141}142 143; Multi-use Test Cases for `shl`144declare void @use(i64)145 146define i64 @test_shl_multi_use_add(i64 %x) {147; CHECK-LABEL: define i64 @test_shl_multi_use_add(148; CHECK-SAME: i64 [[X:%.*]]) {149; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1150; CHECK-NEXT: call void @use(i64 [[X1]])151; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[X]], 3152; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])153; CHECK-NEXT: ret i64 [[MAX]]154;155 %x1 = add i64 %x, 1156 call void @use(i64 %x1)157 %shl = shl nuw i64 %x, 3158 %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)159 ret i64 %max160}161 162define i64 @test_shl_multi_use_shl(i64 %x) {163; CHECK-LABEL: define i64 @test_shl_multi_use_shl(164; CHECK-SAME: i64 [[X:%.*]]) {165; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 [[X]], 2166; CHECK-NEXT: call void @use(i64 [[SHL]])167; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0168; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[SHL]]169; CHECK-NEXT: ret i64 [[MAX]]170;171 %x1 = add i64 %x, 1172 %shl = shl nuw i64 %x, 2173 call void @use(i64 %shl)174 %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)175 ret i64 %max176}177 178; Positive Test Cases for `mul`179 180define i64 @test_mul_by_3(i64 %x) {181; CHECK-LABEL: define i64 @test_mul_by_3(182; CHECK-SAME: i64 [[X:%.*]]) {183; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3184; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0185; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[MUL]]186; CHECK-NEXT: ret i64 [[MAX]]187;188 %x1 = add i64 %x, 1189 %mul = mul nuw i64 %x, 3190 %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)191 ret i64 %max192}193 194define i64 @test_mul_by_5(i64 %x) {195; CHECK-LABEL: define i64 @test_mul_by_5(196; CHECK-SAME: i64 [[X:%.*]]) {197; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 5198; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0199; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[MUL]]200; CHECK-NEXT: ret i64 [[MAX]]201;202 %x1 = add i64 %x, 1203 %mul = mul nuw i64 %x, 5204 %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)205 ret i64 %max206}207 208define i64 @test_mul_with_nsw(i64 %x) {209; CHECK-LABEL: define i64 @test_mul_with_nsw(210; CHECK-SAME: i64 [[X:%.*]]) {211; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i64 [[X]], 3212; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0213; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[MUL]]214; CHECK-NEXT: ret i64 [[MAX]]215;216 %x1 = add i64 %x, 1217 %mul = mul nuw nsw i64 %x, 3218 %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)219 ret i64 %max220}221 222define <2 x i64> @test_mul_vector_by_3(<2 x i64> %x) {223; CHECK-LABEL: define <2 x i64> @test_mul_vector_by_3(224; CHECK-SAME: <2 x i64> [[X:%.*]]) {225; CHECK-NEXT: [[MUL:%.*]] = mul nuw <2 x i64> [[X]], splat (i64 3)226; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X]], zeroinitializer227; CHECK-NEXT: [[MAX:%.*]] = select <2 x i1> [[TMP1]], <2 x i64> splat (i64 1), <2 x i64> [[MUL]]228; CHECK-NEXT: ret <2 x i64> [[MAX]]229;230 %x1 = add <2 x i64> %x, <i64 1, i64 1>231 %mul = mul nuw <2 x i64> %x, <i64 3, i64 3>232 %max = call <2 x i64> @llvm.umax.v2i64(<2 x i64> %mul, <2 x i64> %x1)233 ret <2 x i64> %max234}235 236; Commuted Test Cases for `mul`237 238define i64 @test_mul_max_commuted(i64 %x) {239; CHECK-LABEL: define i64 @test_mul_max_commuted(240; CHECK-SAME: i64 [[X:%.*]]) {241; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3242; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0243; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[MUL]]244; CHECK-NEXT: ret i64 [[MAX]]245;246 %x1 = add i64 %x, 1247 %mul = mul nuw i64 %x, 3248 %max = call i64 @llvm.umax.i64(i64 %x1, i64 %mul)249 ret i64 %max250}251 252; Negative Test Cases for `mul`253 254define i64 @test_mul_by_zero(i64 %x) {255; CHECK-LABEL: define i64 @test_mul_by_zero(256; CHECK-SAME: i64 [[X:%.*]]) {257; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1258; CHECK-NEXT: ret i64 [[X1]]259;260 %x1 = add i64 %x, 1261 %mul = mul nuw i64 %x, 0262 %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)263 ret i64 %max264}265 266define i64 @test_mul_by_1(i64 %x) {267; CHECK-LABEL: define i64 @test_mul_by_1(268; CHECK-SAME: i64 [[X:%.*]]) {269; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1270; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[X]], i64 [[X1]])271; CHECK-NEXT: ret i64 [[MAX]]272;273 %x1 = add i64 %x, 1274 %mul = mul nuw i64 %x, 1275 %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)276 ret i64 %max277}278 279define i64 @test_mul_add_by_2(i64 %x) {280; CHECK-LABEL: define i64 @test_mul_add_by_2(281; CHECK-SAME: i64 [[X:%.*]]) {282; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 2283; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3284; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])285; CHECK-NEXT: ret i64 [[MAX]]286;287 %x1 = add i64 %x, 2288 %mul = mul nuw i64 %x, 3289 %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)290 ret i64 %max291}292 293define i64 @test_mul_without_nuw(i64 %x) {294; CHECK-LABEL: define i64 @test_mul_without_nuw(295; CHECK-SAME: i64 [[X:%.*]]) {296; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1297; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[X]], 3298; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])299; CHECK-NEXT: ret i64 [[MAX]]300;301 %x1 = add i64 %x, 1302 %mul = mul i64 %x, 3303 %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)304 ret i64 %max305}306 307define i64 @test_mul_umin(i64 %x) {308; CHECK-LABEL: define i64 @test_mul_umin(309; CHECK-SAME: i64 [[X:%.*]]) {310; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1311; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3312; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umin.i64(i64 [[MUL]], i64 [[X1]])313; CHECK-NEXT: ret i64 [[MAX]]314;315 %x1 = add i64 %x, 1316 %mul = mul nuw i64 %x, 3317 %max = call i64 @llvm.umin.i64(i64 %mul, i64 %x1)318 ret i64 %max319}320 321; Multi-use Test Cases for `mul`322 323define i64 @test_mul_multi_use_add(i64 %x) {324; CHECK-LABEL: define i64 @test_mul_multi_use_add(325; CHECK-SAME: i64 [[X:%.*]]) {326; CHECK-NEXT: [[X1:%.*]] = add i64 [[X]], 1327; CHECK-NEXT: call void @use(i64 [[X1]])328; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[X]], 3329; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])330; CHECK-NEXT: ret i64 [[MAX]]331;332 %x1 = add i64 %x, 1333 call void @use(i64 %x1)334 %mul = mul nuw i64 %x, 3335 %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)336 ret i64 %max337}338 339define i64 @test_mul_multi_use_mul(i64 %x) {340; CHECK-LABEL: define i64 @test_mul_multi_use_mul(341; CHECK-SAME: i64 [[X:%.*]]) {342; CHECK-NEXT: [[MUL:%.*]] = mul nuw i64 [[X]], 3343; CHECK-NEXT: call void @use(i64 [[MUL]])344; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X]], 0345; CHECK-NEXT: [[MAX:%.*]] = select i1 [[TMP1]], i64 1, i64 [[MUL]]346; CHECK-NEXT: ret i64 [[MAX]]347;348 %x1 = add i64 %x, 1349 %mul = mul nuw i64 %x, 3350 call void @use(i64 %mul)351 %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)352 ret i64 %max353}354