; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6 ; RUN: opt -passes='print' -disable-output %s 2>&1 | FileCheck %s declare i32 @llvm.smax.i32(i32, i32) declare i32 @llvm.umax.i32(i32, i32) define i64 @smax_fold_basic(i32 %x) { ; CHECK-LABEL: 'smax_fold_basic' ; CHECK-NEXT: Classifying expressions for: @smax_fold_basic ; CHECK-NEXT: %smax = call i32 @llvm.smax.i32(i32 %x, i32 5) ; CHECK-NEXT: --> (5 smax %x) U: [5,-2147483648) S: [5,-2147483648) ; CHECK-NEXT: %add = add nsw i32 -5, %smax ; CHECK-NEXT: --> (-5 + (5 smax %x)) U: [0,2147483643) S: [0,2147483643) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (-5 + (zext i32 (5 smax %x) to i64)) U: [0,2147483643) S: [0,2147483643) ; CHECK-NEXT: Determining loop execution counts for: @smax_fold_basic ; %smax = call i32 @llvm.smax.i32(i32 %x, i32 5) %add = add nsw i32 -5, %smax %ext = zext i32 %add to i64 ret i64 %ext } define i64 @smax_fold_larger_k(i32 %x) { ; CHECK-LABEL: 'smax_fold_larger_k' ; CHECK-NEXT: Classifying expressions for: @smax_fold_larger_k ; CHECK-NEXT: %smax = call i32 @llvm.smax.i32(i32 %x, i32 10) ; CHECK-NEXT: --> (10 smax %x) U: [10,-2147483648) S: [10,-2147483648) ; CHECK-NEXT: %add = add nsw i32 -3, %smax ; CHECK-NEXT: --> (-3 + (10 smax %x)) U: [7,2147483645) S: [7,2147483645) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (-3 + (zext i32 (10 smax %x) to i64)) U: [7,2147483645) S: [7,2147483645) ; CHECK-NEXT: Determining loop execution counts for: @smax_fold_larger_k ; %smax = call i32 @llvm.smax.i32(i32 %x, i32 10) %add = add nsw i32 -3, %smax %ext = zext i32 %add to i64 ret i64 %ext } define i64 @smax_no_fold_k_too_small(i32 %x) { ; CHECK-LABEL: 'smax_no_fold_k_too_small' ; CHECK-NEXT: Classifying expressions for: @smax_no_fold_k_too_small ; CHECK-NEXT: %smax = call i32 @llvm.smax.i32(i32 %x, i32 4) ; CHECK-NEXT: --> (4 smax %x) U: [4,-2147483648) S: [4,-2147483648) ; CHECK-NEXT: %add = add nsw i32 -5, %smax ; CHECK-NEXT: --> (-5 + (4 smax %x)) U: [-1,2147483643) S: [-1,2147483643) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (zext i32 (-5 + (4 smax %x)) to i64) U: [0,4294967296) S: [0,4294967296) ; CHECK-NEXT: Determining loop execution counts for: @smax_no_fold_k_too_small ; %smax = call i32 @llvm.smax.i32(i32 %x, i32 4) %add = add nsw i32 -5, %smax %ext = zext i32 %add to i64 ret i64 %ext } define i64 @smax_no_fold_k_negative(i32 %x) { ; CHECK-LABEL: 'smax_no_fold_k_negative' ; CHECK-NEXT: Classifying expressions for: @smax_no_fold_k_negative ; CHECK-NEXT: %smax = call i32 @llvm.smax.i32(i32 %x, i32 -1) ; CHECK-NEXT: --> (-1 smax %x) U: [-1,-2147483648) S: [-1,-2147483648) ; CHECK-NEXT: %add = add nsw i32 -5, %smax ; CHECK-NEXT: --> (-5 + (-1 smax %x)) U: [-6,2147483643) S: [-6,2147483643) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (zext i32 (-5 + (-1 smax %x)) to i64) U: [0,4294967296) S: [0,4294967296) ; CHECK-NEXT: Determining loop execution counts for: @smax_no_fold_k_negative ; %smax = call i32 @llvm.smax.i32(i32 %x, i32 -1) %add = add nsw i32 -5, %smax %ext = zext i32 %add to i64 ret i64 %ext } define i64 @mul_umax_fold(i8 %x) { ; CHECK-LABEL: 'mul_umax_fold' ; CHECK-NEXT: Classifying expressions for: @mul_umax_fold ; CHECK-NEXT: %zx = zext i8 %x to i32 ; CHECK-NEXT: --> (zext i8 %x to i32) U: [0,256) S: [0,256) ; CHECK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %zx, i32 3) ; CHECK-NEXT: --> (3 umax (zext i8 %x to i32)) U: [3,256) S: [3,256) ; CHECK-NEXT: %mul = mul nuw nsw i32 4, %umax ; CHECK-NEXT: --> (4 * (3 umax (zext i8 %x to i32))) U: [12,1021) S: [12,1021) ; CHECK-NEXT: %add = add nsw i32 -12, %mul ; CHECK-NEXT: --> (-12 + (4 * (3 umax (zext i8 %x to i32)))) U: [0,1009) S: [0,1009) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (zext i32 (-12 + (4 * (3 umax (zext i8 %x to i32)))) to i64) U: [0,1009) S: [0,1009) ; CHECK-NEXT: Determining loop execution counts for: @mul_umax_fold ; %zx = zext i8 %x to i32 %umax = call i32 @llvm.umax.i32(i32 %zx, i32 3) %mul = mul nuw nsw i32 4, %umax %add = add nsw i32 -12, %mul %ext = zext i32 %add to i64 ret i64 %ext } define i64 @mul_umax_fold_round_up(i8 %x) { ; CHECK-LABEL: 'mul_umax_fold_round_up' ; CHECK-NEXT: Classifying expressions for: @mul_umax_fold_round_up ; CHECK-NEXT: %zx = zext i8 %x to i32 ; CHECK-NEXT: --> (zext i8 %x to i32) U: [0,256) S: [0,256) ; CHECK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %zx, i32 3) ; CHECK-NEXT: --> (3 umax (zext i8 %x to i32)) U: [3,256) S: [3,256) ; CHECK-NEXT: %mul = mul nuw nsw i32 4, %umax ; CHECK-NEXT: --> (4 * (3 umax (zext i8 %x to i32))) U: [12,1021) S: [12,1021) ; CHECK-NEXT: %add = add nsw i32 -10, %mul ; CHECK-NEXT: --> (-10 + (4 * (3 umax (zext i8 %x to i32)))) U: [2,1011) S: [2,1011) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (2 + (zext i32 (-12 + (4 * (3 umax (zext i8 %x to i32)))) to i64)) U: [2,1011) S: [2,1011) ; CHECK-NEXT: Determining loop execution counts for: @mul_umax_fold_round_up ; %zx = zext i8 %x to i32 %umax = call i32 @llvm.umax.i32(i32 %zx, i32 3) %mul = mul nuw nsw i32 4, %umax %add = add nsw i32 -10, %mul %ext = zext i32 %add to i64 ret i64 %ext } define i64 @mul_umax_no_fold_bound_not_met(i8 %x) { ; CHECK-LABEL: 'mul_umax_no_fold_bound_not_met' ; CHECK-NEXT: Classifying expressions for: @mul_umax_no_fold_bound_not_met ; CHECK-NEXT: %zx = zext i8 %x to i32 ; CHECK-NEXT: --> (zext i8 %x to i32) U: [0,256) S: [0,256) ; CHECK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %zx, i32 3) ; CHECK-NEXT: --> (3 umax (zext i8 %x to i32)) U: [3,256) S: [3,256) ; CHECK-NEXT: %mul = mul nuw nsw i32 4, %umax ; CHECK-NEXT: --> (4 * (3 umax (zext i8 %x to i32))) U: [12,1021) S: [12,1021) ; CHECK-NEXT: %add = add nsw i32 -13, %mul ; CHECK-NEXT: --> (-13 + (4 * (3 umax (zext i8 %x to i32)))) U: [-1,1008) S: [-1,1008) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (3 + (zext i32 (-16 + (4 * (3 umax (zext i8 %x to i32)))) to i64)) U: [3,4294967296) S: [3,4294967299) ; CHECK-NEXT: Determining loop execution counts for: @mul_umax_no_fold_bound_not_met ; %zx = zext i8 %x to i32 %umax = call i32 @llvm.umax.i32(i32 %zx, i32 3) %mul = mul nuw nsw i32 4, %umax %add = add nsw i32 -13, %mul %ext = zext i32 %add to i64 ret i64 %ext } define i64 @mul_smax_fold(i8 %x) { ; CHECK-LABEL: 'mul_smax_fold' ; CHECK-NEXT: Classifying expressions for: @mul_smax_fold ; CHECK-NEXT: %zx = zext i8 %x to i32 ; CHECK-NEXT: --> (zext i8 %x to i32) U: [0,256) S: [0,256) ; CHECK-NEXT: %smax = call i32 @llvm.smax.i32(i32 %zx, i32 3) ; CHECK-NEXT: --> (3 smax (zext i8 %x to i32)) U: [3,256) S: [3,256) ; CHECK-NEXT: %mul = mul nuw nsw i32 4, %smax ; CHECK-NEXT: --> (4 * (3 smax (zext i8 %x to i32))) U: [12,1021) S: [12,1021) ; CHECK-NEXT: %add = add nsw i32 -8, %mul ; CHECK-NEXT: --> (-8 + (4 * (3 smax (zext i8 %x to i32)))) U: [4,1013) S: [4,1013) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (zext i32 (-8 + (4 * (3 smax (zext i8 %x to i32)))) to i64) U: [4,1013) S: [4,1013) ; CHECK-NEXT: Determining loop execution counts for: @mul_smax_fold ; %zx = zext i8 %x to i32 %smax = call i32 @llvm.smax.i32(i32 %zx, i32 3) %mul = mul nuw nsw i32 4, %smax %add = add nsw i32 -8, %mul %ext = zext i32 %add to i64 ret i64 %ext } define i64 @const_fold_exact() { ; CHECK-LABEL: 'const_fold_exact' ; CHECK-NEXT: Classifying expressions for: @const_fold_exact ; CHECK-NEXT: %add = add nsw i32 -5, 5 ; CHECK-NEXT: --> 0 U: [0,1) S: [0,1) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> 0 U: [0,1) S: [0,1) ; CHECK-NEXT: Determining loop execution counts for: @const_fold_exact ; %add = add nsw i32 -5, 5 %ext = zext i32 %add to i64 ret i64 %ext } define i64 @const_fold_larger() { ; CHECK-LABEL: 'const_fold_larger' ; CHECK-NEXT: Classifying expressions for: @const_fold_larger ; CHECK-NEXT: %add = add nsw i32 -3, 100 ; CHECK-NEXT: --> 97 U: [97,98) S: [97,98) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> 97 U: [97,98) S: [97,98) ; CHECK-NEXT: Determining loop execution counts for: @const_fold_larger ; %add = add nsw i32 -3, 100 %ext = zext i32 %add to i64 ret i64 %ext } define i64 @umax_no_mul_no_fold(i32 %x) { ; CHECK-LABEL: 'umax_no_mul_no_fold' ; CHECK-NEXT: Classifying expressions for: @umax_no_mul_no_fold ; CHECK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %x, i32 5) ; CHECK-NEXT: --> (5 umax %x) U: [5,0) S: [5,0) ; CHECK-NEXT: %add = add nsw i32 -5, %umax ; CHECK-NEXT: --> (-5 + (5 umax %x)) U: [0,-5) S: [0,-5) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (zext i32 (-5 + (5 umax %x)) to i64) U: [0,4294967291) S: [0,4294967291) ; CHECK-NEXT: Determining loop execution counts for: @umax_no_mul_no_fold ; %umax = call i32 @llvm.umax.i32(i32 %x, i32 5) %add = add nsw i32 -5, %umax %ext = zext i32 %add to i64 ret i64 %ext } define i64 @umax_zext_fold(i8 %x) { ; CHECK-LABEL: 'umax_zext_fold' ; CHECK-NEXT: Classifying expressions for: @umax_zext_fold ; CHECK-NEXT: %zx = zext i8 %x to i32 ; CHECK-NEXT: --> (zext i8 %x to i32) U: [0,256) S: [0,256) ; CHECK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %zx, i32 5) ; CHECK-NEXT: --> (5 umax (zext i8 %x to i32)) U: [5,256) S: [5,256) ; CHECK-NEXT: %add = add nsw i32 -5, %umax ; CHECK-NEXT: --> (-5 + (5 umax (zext i8 %x to i32))) U: [0,251) S: [0,251) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (zext i32 (-5 + (5 umax (zext i8 %x to i32))) to i64) U: [0,251) S: [0,251) ; CHECK-NEXT: Determining loop execution counts for: @umax_zext_fold ; %zx = zext i8 %x to i32 %umax = call i32 @llvm.umax.i32(i32 %zx, i32 5) %add = add nsw i32 -5, %umax %ext = zext i32 %add to i64 ret i64 %ext } define i64 @zext_op_fold_positive_c(i8 %x) { ; CHECK-LABEL: 'zext_op_fold_positive_c' ; CHECK-NEXT: Classifying expressions for: @zext_op_fold_positive_c ; CHECK-NEXT: %zx = zext i8 %x to i32 ; CHECK-NEXT: --> (zext i8 %x to i32) U: [0,256) S: [0,256) ; CHECK-NEXT: %add = add nsw i32 3, %zx ; CHECK-NEXT: --> (3 + (zext i8 %x to i32)) U: [3,259) S: [3,259) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (3 + (zext i8 %x to i64)) U: [3,259) S: [3,259) ; CHECK-NEXT: Determining loop execution counts for: @zext_op_fold_positive_c ; %zx = zext i8 %x to i32 %add = add nsw i32 3, %zx %ext = zext i32 %add to i64 ret i64 %ext } define i64 @zext_op_no_fold_negative_c(i16 %x) { ; CHECK-LABEL: 'zext_op_no_fold_negative_c' ; CHECK-NEXT: Classifying expressions for: @zext_op_no_fold_negative_c ; CHECK-NEXT: %zx = zext i16 %x to i32 ; CHECK-NEXT: --> (zext i16 %x to i32) U: [0,65536) S: [0,65536) ; CHECK-NEXT: %add = add nsw i32 -5, %zx ; CHECK-NEXT: --> (-5 + (zext i16 %x to i32)) U: [-5,65531) S: [-5,65531) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (zext i32 (-5 + (zext i16 %x to i32)) to i64) U: [0,4294967296) S: [0,4294967296) ; CHECK-NEXT: Determining loop execution counts for: @zext_op_no_fold_negative_c ; ; No fold: C = -5 is negative and zext has min 0, so -5 + 0 < 0. %zx = zext i16 %x to i32 %add = add nsw i32 -5, %zx %ext = zext i32 %add to i64 ret i64 %ext } define i64 @mul_zext_fold_positive_c(i8 %x) { ; CHECK-LABEL: 'mul_zext_fold_positive_c' ; CHECK-NEXT: Classifying expressions for: @mul_zext_fold_positive_c ; CHECK-NEXT: %zx = zext i8 %x to i32 ; CHECK-NEXT: --> (zext i8 %x to i32) U: [0,256) S: [0,256) ; CHECK-NEXT: %mul = mul nuw nsw i32 4, %zx ; CHECK-NEXT: --> (4 * (zext i8 %x to i32)) U: [0,1021) S: [0,1021) ; CHECK-NEXT: %add = add nsw i32 2, %mul ; CHECK-NEXT: --> (2 + (4 * (zext i8 %x to i32))) U: [2,1023) S: [2,1023) ; CHECK-NEXT: %ext = zext i32 %add to i64 ; CHECK-NEXT: --> (2 + (4 * (zext i8 %x to i64))) U: [2,1023) S: [2,1023) ; CHECK-NEXT: Determining loop execution counts for: @mul_zext_fold_positive_c ; %zx = zext i8 %x to i32 %mul = mul nuw nsw i32 4, %zx %add = add nsw i32 2, %mul %ext = zext i32 %add to i64 ret i64 %ext }