296 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 62; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i32)5 6define i1 @test_i32_eq(i32 %x) {7; CHECK-LABEL: define i1 @test_i32_eq(8; CHECK-SAME: i32 [[X:%.*]]) {9; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 9510; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], 25611; CHECK-NEXT: ret i1 [[CMP]]12;13 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 -95)14 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 160)15 %cmp = icmp eq i32 %v2, %x16 ret i1 %cmp17}18 19define i1 @test_i32_ne(i32 %x) {20; CHECK-LABEL: define i1 @test_i32_ne(21; CHECK-SAME: i32 [[X:%.*]]) {22; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -16123; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], -25624; CHECK-NEXT: ret i1 [[CMP]]25;26 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 -95)27 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 160)28 %cmp = icmp ne i32 %v2, %x29 ret i1 %cmp30}31 32define i1 @test_i32_eq_no_add(i32 %x) {33; CHECK-LABEL: define i1 @test_i32_eq_no_add(34; CHECK-SAME: i32 [[X:%.*]]) {35; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], 16136; CHECK-NEXT: ret i1 [[CMP]]37;38 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 0)39 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 160)40 %cmp = icmp eq i32 %v2, %x41 ret i1 %cmp42}43 44define i1 @test_i32_ne_no_add(i32 %x) {45; CHECK-LABEL: define i1 @test_i32_ne_no_add(46; CHECK-SAME: i32 [[X:%.*]]) {47; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X]], 16048; CHECK-NEXT: ret i1 [[CMP]]49;50 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 0)51 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 160)52 %cmp = icmp ne i32 %v2, %x53 ret i1 %cmp54}55 56define i1 @test_unsigned_eq(i32 %x) {57; CHECK-LABEL: define i1 @test_unsigned_eq(58; CHECK-SAME: i32 [[X:%.*]]) {59; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -1060; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], 9161; CHECK-NEXT: ret i1 [[CMP]]62;63 %v1 = tail call i32 @llvm.umax.i32(i32 %x, i32 10)64 %v2 = tail call i32 @llvm.umin.i32(i32 %v1, i32 100)65 %cmp = icmp eq i32 %v2, %x66 ret i1 %cmp67}68 69define i1 @test_unsigned_ne(i32 %x) {70; CHECK-LABEL: define i1 @test_unsigned_ne(71; CHECK-SAME: i32 [[X:%.*]]) {72; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -10173; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], -9174; CHECK-NEXT: ret i1 [[CMP]]75;76 %v1 = tail call i32 @llvm.umax.i32(i32 %x, i32 10)77 %v2 = tail call i32 @llvm.umin.i32(i32 %v1, i32 100)78 %cmp = icmp ne i32 %v2, %x79 ret i1 %cmp80}81 82 83; Different bit widths84define i1 @test_i8_eq(i8 %x) {85; CHECK-LABEL: define i1 @test_i8_eq(86; CHECK-SAME: i8 [[X:%.*]]) {87; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], 5088; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[TMP1]], 10189; CHECK-NEXT: ret i1 [[CMP]]90;91 %v1 = tail call i8 @llvm.smax.i8(i8 %x, i8 -50)92 %v2 = tail call i8 @llvm.smin.i8(i8 %v1, i8 50)93 %cmp = icmp eq i8 %v2, %x94 ret i1 %cmp95}96 97define i1 @test_i16_eq(i16 %x) {98; CHECK-LABEL: define i1 @test_i16_eq(99; CHECK-SAME: i16 [[X:%.*]]) {100; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[X]], 1000101; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[TMP1]], 2001102; CHECK-NEXT: ret i1 [[CMP]]103;104 %v1 = tail call i16 @llvm.smax.i16(i16 %x, i16 -1000)105 %v2 = tail call i16 @llvm.smin.i16(i16 %v1, i16 1000)106 %cmp = icmp eq i16 %v2, %x107 ret i1 %cmp108}109 110define i1 @test_i64_eq(i64 %x) {111; CHECK-LABEL: define i1 @test_i64_eq(112; CHECK-SAME: i64 [[X:%.*]]) {113; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X]], 1114; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[TMP1]], -1115; CHECK-NEXT: ret i1 [[CMP]]116;117 %v1 = tail call i64 @llvm.smax.i64(i64 %x, i64 -1)118 %v2 = tail call i64 @llvm.smin.i64(i64 %v1, i64 9223372036854775806)119 %cmp = icmp eq i64 %v2, %x120 ret i1 %cmp121}122 123; Negative tests - wrong predicate124define i1 @test_wrong_pred_slt(i32 %x) {125; CHECK-LABEL: define i1 @test_wrong_pred_slt(126; CHECK-SAME: i32 [[X:%.*]]) {127; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], 160128; CHECK-NEXT: ret i1 [[CMP]]129;130 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 -95)131 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 160)132 %cmp = icmp slt i32 %v2, %x133 ret i1 %cmp134}135 136 137; Negative tests - not a clamp pattern138define i1 @test_not_clamp_pattern(i32 %x, i32 %y) {139; CHECK-LABEL: define i1 @test_not_clamp_pattern(140; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {141; CHECK-NEXT: [[V1:%.*]] = tail call i32 @llvm.smax.i32(i32 [[Y]], i32 -95)142; CHECK-NEXT: [[V2:%.*]] = tail call i32 @llvm.smin.i32(i32 [[V1]], i32 160)143; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V2]], [[X]]144; CHECK-NEXT: ret i1 [[CMP]]145;146 %v1 = tail call i32 @llvm.smax.i32(i32 %y, i32 -95)147 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 160)148 %cmp = icmp eq i32 %v2, %x149 ret i1 %cmp150}151 152; Negative tests - Lo >= Hi153define i1 @test_invalid_range(i32 %x) {154; CHECK-LABEL: define i1 @test_invalid_range(155; CHECK-SAME: i32 [[X:%.*]]) {156; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 50157; CHECK-NEXT: ret i1 [[CMP]]158;159 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 100)160 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 50)161 %cmp = icmp eq i32 %v2, %x162 ret i1 %cmp163}164 165; Negative tests - Lo is minimum signed value166define i1 @test_lo_min_signed(i32 %x) {167; CHECK-LABEL: define i1 @test_lo_min_signed(168; CHECK-SAME: i32 [[X:%.*]]) {169; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 161170; CHECK-NEXT: ret i1 [[CMP]]171;172 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 -2147483648)173 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 160)174 %cmp = icmp eq i32 %v2, %x175 ret i1 %cmp176}177 178; Negative tests - Hi is maximum signed value179define i1 @test_hi_max_signed(i32 %x) {180; CHECK-LABEL: define i1 @test_hi_max_signed(181; CHECK-SAME: i32 [[X:%.*]]) {182; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], -96183; CHECK-NEXT: ret i1 [[CMP]]184;185 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 -95)186 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 2147483647)187 %cmp = icmp eq i32 %v2, %x188 ret i1 %cmp189}190 191; Negative tests - Hi is maximum unsigned value192define i1 @test_hi_max_unsigned(i32 %x) {193; CHECK-LABEL: define i1 @test_hi_max_unsigned(194; CHECK-SAME: i32 [[X:%.*]]) {195; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X]], 9196; CHECK-NEXT: ret i1 [[CMP]]197;198 %v1 = tail call i32 @llvm.umax.i32(i32 %x, i32 10)199 %v2 = tail call i32 @llvm.umin.i32(i32 %v1, i32 4294967295)200 %cmp = icmp eq i32 %v2, %x201 ret i1 %cmp202}203 204; Multi-use tests - multiple uses of max205define i1 @test_multi_use_max(i32 %x) {206; CHECK-LABEL: define i1 @test_multi_use_max(207; CHECK-SAME: i32 [[X:%.*]]) {208; CHECK-NEXT: [[V1:%.*]] = tail call i32 @llvm.smax.i32(i32 [[X]], i32 -95)209; CHECK-NEXT: call void @use(i32 [[V1]])210; CHECK-NEXT: [[V2:%.*]] = tail call i32 @llvm.smin.i32(i32 [[V1]], i32 160)211; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V2]], [[X]]212; CHECK-NEXT: ret i1 [[CMP]]213;214 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 -95)215 call void @use(i32 %v1)216 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 160)217 %cmp = icmp eq i32 %v2, %x218 ret i1 %cmp219}220 221; Multi-use tests - multiple uses of min222define i1 @test_multi_use_min(i32 %x) {223; CHECK-LABEL: define i1 @test_multi_use_min(224; CHECK-SAME: i32 [[X:%.*]]) {225; CHECK-NEXT: [[V1:%.*]] = tail call i32 @llvm.smax.i32(i32 [[X]], i32 -95)226; CHECK-NEXT: [[V2:%.*]] = tail call i32 @llvm.smin.i32(i32 [[V1]], i32 160)227; CHECK-NEXT: call void @use(i32 [[V2]])228; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V2]], [[X]]229; CHECK-NEXT: ret i1 [[CMP]]230;231 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 -95)232 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 160)233 call void @use(i32 %v2)234 %cmp = icmp eq i32 %v2, %x235 ret i1 %cmp236}237 238; Commuted tests239define i1 @test_commuted_eq(i32 %x) {240; CHECK-LABEL: define i1 @test_commuted_eq(241; CHECK-SAME: i32 [[X:%.*]]) {242; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], 95243; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], 256244; CHECK-NEXT: ret i1 [[CMP]]245;246 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 -95)247 %v2 = tail call i32 @llvm.smin.i32(i32 %v1, i32 160)248 %cmp = icmp eq i32 %x, %v2249 ret i1 %cmp250}251 252 253; Vector tests - splat constants254define <2 x i1> @test_vec_splat_eq(<2 x i32> %x) {255; CHECK-LABEL: define <2 x i1> @test_vec_splat_eq(256; CHECK-SAME: <2 x i32> [[X:%.*]]) {257; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X]], splat (i32 50)258; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 101)259; CHECK-NEXT: ret <2 x i1> [[CMP]]260;261 %v1 = tail call <2 x i32> @llvm.smax.v2i32(<2 x i32> %x, <2 x i32> <i32 -50, i32 -50>)262 %v2 = tail call <2 x i32> @llvm.smin.v2i32(<2 x i32> %v1, <2 x i32> <i32 50, i32 50>)263 %cmp = icmp eq <2 x i32> %v2, %x264 ret <2 x i1> %cmp265}266 267; Vector tests - poison elements268define <2 x i1> @test_vec_poison_eq(<2 x i32> %x) {269; CHECK-LABEL: define <2 x i1> @test_vec_poison_eq(270; CHECK-SAME: <2 x i32> [[X:%.*]]) {271; CHECK-NEXT: [[V1:%.*]] = tail call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[X]], <2 x i32> <i32 -50, i32 poison>)272; CHECK-NEXT: [[V2:%.*]] = tail call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[V1]], <2 x i32> <i32 50, i32 poison>)273; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V2]], [[X]]274; CHECK-NEXT: ret <2 x i1> [[CMP]]275;276 %v1 = tail call <2 x i32> @llvm.smax.v2i32(<2 x i32> %x, <2 x i32> <i32 -50, i32 poison>)277 %v2 = tail call <2 x i32> @llvm.smin.v2i32(<2 x i32> %v1, <2 x i32> <i32 50, i32 poison>)278 %cmp = icmp eq <2 x i32> %v2, %x279 ret <2 x i1> %cmp280}281 282; Vector tests - non-splat283define <2 x i1> @test_vec_non_splat_eq(<2 x i32> %x) {284; CHECK-LABEL: define <2 x i1> @test_vec_non_splat_eq(285; CHECK-SAME: <2 x i32> [[X:%.*]]) {286; CHECK-NEXT: [[V1:%.*]] = tail call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[X]], <2 x i32> <i32 -50, i32 -30>)287; CHECK-NEXT: [[V2:%.*]] = tail call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[V1]], <2 x i32> <i32 50, i32 70>)288; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V2]], [[X]]289; CHECK-NEXT: ret <2 x i1> [[CMP]]290;291 %v1 = tail call <2 x i32> @llvm.smax.v2i32(<2 x i32> %x, <2 x i32> <i32 -50, i32 -30>)292 %v2 = tail call <2 x i32> @llvm.smin.v2i32(<2 x i32> %v1, <2 x i32> <i32 50, i32 70>)293 %cmp = icmp eq <2 x i32> %v2, %x294 ret <2 x i1> %cmp295}296