1039 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=armv4t-eabi %s -o - | FileCheck %s --check-prefix=V4T3; RUN: llc -mtriple=armv6-eabi %s -o - | FileCheck %s --check-prefix=V64; RUN: llc -mtriple=armv6t2-eabi %s -o - | FileCheck %s --check-prefix=V6T25 6; Check for several conditions that should result in USAT.7; For example, the base test is equivalent to8; x < 0 ? 0 : (x > k ? k : x) in C. All patterns that bound x9; to the interval [0, k] where k + 1 is a power of 2 can be10; transformed into USAT. At the end there are some tests11; checking that conditionals are not transformed if they don't12; match the right pattern.13 14;15; Base tests with different bit widths16;17 18; x < 0 ? 0 : (x > k ? k : x)19; 32-bit base test20define i32 @unsigned_sat_base_32bit(i32 %x) #0 {21; V4T-LABEL: unsigned_sat_base_32bit:22; V4T: @ %bb.0: @ %entry23; V4T-NEXT: ldr r1, .LCPI0_024; V4T-NEXT: cmp r0, r125; V4T-NEXT: movlt r1, r026; V4T-NEXT: bic r0, r1, r1, asr #3127; V4T-NEXT: bx lr28; V4T-NEXT: .p2align 229; V4T-NEXT: @ %bb.1:30; V4T-NEXT: .LCPI0_0:31; V4T-NEXT: .long 8388607 @ 0x7fffff32;33; V6-LABEL: unsigned_sat_base_32bit:34; V6: @ %bb.0: @ %entry35; V6-NEXT: ldr r1, .LCPI0_036; V6-NEXT: cmp r0, r137; V6-NEXT: movlt r1, r038; V6-NEXT: bic r0, r1, r1, asr #3139; V6-NEXT: bx lr40; V6-NEXT: .p2align 241; V6-NEXT: @ %bb.1:42; V6-NEXT: .LCPI0_0:43; V6-NEXT: .long 8388607 @ 0x7fffff44;45; V6T2-LABEL: unsigned_sat_base_32bit:46; V6T2: @ %bb.0: @ %entry47; V6T2-NEXT: movw r1, #6553548; V6T2-NEXT: movt r1, #12749; V6T2-NEXT: cmp r0, r150; V6T2-NEXT: movlt r1, r051; V6T2-NEXT: bic r0, r1, r1, asr #3152; V6T2-NEXT: bx lr53entry:54 %0 = icmp slt i32 %x, 838860755 %saturateUp = select i1 %0, i32 %x, i32 838860756 %1 = icmp sgt i32 %saturateUp, 057 %saturateLow = select i1 %1, i32 %saturateUp, i32 058 ret i32 %saturateLow59}60 61; x < 0 ? 0 : (x > k ? k : x)62; 16-bit base test63define i16 @unsigned_sat_base_16bit(i16 %x) #0 {64; V4T-LABEL: unsigned_sat_base_16bit:65; V4T: @ %bb.0: @ %entry66; V4T-NEXT: mov r2, #25567; V4T-NEXT: lsl r1, r0, #1668; V4T-NEXT: orr r2, r2, #179269; V4T-NEXT: asr r1, r1, #1670; V4T-NEXT: cmp r1, r271; V4T-NEXT: movlt r2, r072; V4T-NEXT: lsl r0, r2, #1673; V4T-NEXT: bic r0, r2, r0, asr #3174; V4T-NEXT: bx lr75;76; V6-LABEL: unsigned_sat_base_16bit:77; V6: @ %bb.0: @ %entry78; V6-NEXT: mov r2, #25579; V6-NEXT: sxth r1, r080; V6-NEXT: orr r2, r2, #179281; V6-NEXT: cmp r1, r282; V6-NEXT: movlt r2, r083; V6-NEXT: sxth r0, r284; V6-NEXT: bic r0, r2, r0, asr #1585; V6-NEXT: bx lr86;87; V6T2-LABEL: unsigned_sat_base_16bit:88; V6T2: @ %bb.0: @ %entry89; V6T2-NEXT: sxth r1, r090; V6T2-NEXT: movw r2, #204791; V6T2-NEXT: cmp r1, r292; V6T2-NEXT: movlt r2, r093; V6T2-NEXT: sxth r0, r294; V6T2-NEXT: bic r0, r2, r0, asr #1595; V6T2-NEXT: bx lr96entry:97 %0 = icmp slt i16 %x, 204798 %saturateUp = select i1 %0, i16 %x, i16 204799 %1 = icmp sgt i16 %saturateUp, 0100 %saturateLow = select i1 %1, i16 %saturateUp, i16 0101 ret i16 %saturateLow102}103 104; x < 0 ? 0 : (x > k ? k : x)105; 8-bit base test106define i8 @unsigned_sat_base_8bit(i8 %x) #0 {107; V4T-LABEL: unsigned_sat_base_8bit:108; V4T: @ %bb.0: @ %entry109; V4T-NEXT: lsl r1, r0, #24110; V4T-NEXT: asr r1, r1, #24111; V4T-NEXT: cmp r1, #31112; V4T-NEXT: movge r0, #31113; V4T-NEXT: lsl r1, r0, #24114; V4T-NEXT: bic r0, r0, r1, asr #31115; V4T-NEXT: bx lr116;117; V6-LABEL: unsigned_sat_base_8bit:118; V6: @ %bb.0: @ %entry119; V6-NEXT: sxtb r1, r0120; V6-NEXT: cmp r1, #31121; V6-NEXT: movge r0, #31122; V6-NEXT: sxtb r1, r0123; V6-NEXT: bic r0, r0, r1, asr #7124; V6-NEXT: bx lr125;126; V6T2-LABEL: unsigned_sat_base_8bit:127; V6T2: @ %bb.0: @ %entry128; V6T2-NEXT: sxtb r1, r0129; V6T2-NEXT: cmp r1, #31130; V6T2-NEXT: movge r0, #31131; V6T2-NEXT: sxtb r1, r0132; V6T2-NEXT: bic r0, r0, r1, asr #7133; V6T2-NEXT: bx lr134entry:135 %0 = icmp slt i8 %x, 31136 %saturateUp = select i1 %0, i8 %x, i8 31137 %1 = icmp sgt i8 %saturateUp, 0138 %saturateLow = select i1 %1, i8 %saturateUp, i8 0139 ret i8 %saturateLow140}141 142;143; Tests where the conditionals that check for upper and lower bounds,144; or the < and > operators, are arranged in different ways. Only some145; of the possible combinations that lead to USAT are tested.146;147; x < 0 ? 0 : (x < k ? x : k)148define i32 @unsigned_sat_lower_upper_1(i32 %x) #0 {149; V4T-LABEL: unsigned_sat_lower_upper_1:150; V4T: @ %bb.0: @ %entry151; V4T-NEXT: ldr r1, .LCPI3_0152; V4T-NEXT: cmp r0, r1153; V4T-NEXT: movlt r1, r0154; V4T-NEXT: bic r0, r1, r1, asr #31155; V4T-NEXT: bx lr156; V4T-NEXT: .p2align 2157; V4T-NEXT: @ %bb.1:158; V4T-NEXT: .LCPI3_0:159; V4T-NEXT: .long 8388607 @ 0x7fffff160;161; V6-LABEL: unsigned_sat_lower_upper_1:162; V6: @ %bb.0: @ %entry163; V6-NEXT: ldr r1, .LCPI3_0164; V6-NEXT: cmp r0, r1165; V6-NEXT: movlt r1, r0166; V6-NEXT: bic r0, r1, r1, asr #31167; V6-NEXT: bx lr168; V6-NEXT: .p2align 2169; V6-NEXT: @ %bb.1:170; V6-NEXT: .LCPI3_0:171; V6-NEXT: .long 8388607 @ 0x7fffff172;173; V6T2-LABEL: unsigned_sat_lower_upper_1:174; V6T2: @ %bb.0: @ %entry175; V6T2-NEXT: movw r1, #65535176; V6T2-NEXT: movt r1, #127177; V6T2-NEXT: cmp r0, r1178; V6T2-NEXT: movlt r1, r0179; V6T2-NEXT: bic r0, r1, r1, asr #31180; V6T2-NEXT: bx lr181entry:182 %cmpUp = icmp slt i32 %x, 8388607183 %saturateUp = select i1 %cmpUp, i32 %x, i32 8388607184 %0 = icmp sgt i32 %saturateUp, 0185 %saturateLow = select i1 %0, i32 %saturateUp, i32 0186 ret i32 %saturateLow187}188 189; x > 0 ? (x > k ? k : x) : 0190define i32 @unsigned_sat_lower_upper_2(i32 %x) #0 {191; V4T-LABEL: unsigned_sat_lower_upper_2:192; V4T: @ %bb.0: @ %entry193; V4T-NEXT: ldr r1, .LCPI4_0194; V4T-NEXT: cmp r0, r1195; V4T-NEXT: movlt r1, r0196; V4T-NEXT: bic r0, r1, r1, asr #31197; V4T-NEXT: bx lr198; V4T-NEXT: .p2align 2199; V4T-NEXT: @ %bb.1:200; V4T-NEXT: .LCPI4_0:201; V4T-NEXT: .long 8388607 @ 0x7fffff202;203; V6-LABEL: unsigned_sat_lower_upper_2:204; V6: @ %bb.0: @ %entry205; V6-NEXT: ldr r1, .LCPI4_0206; V6-NEXT: cmp r0, r1207; V6-NEXT: movlt r1, r0208; V6-NEXT: bic r0, r1, r1, asr #31209; V6-NEXT: bx lr210; V6-NEXT: .p2align 2211; V6-NEXT: @ %bb.1:212; V6-NEXT: .LCPI4_0:213; V6-NEXT: .long 8388607 @ 0x7fffff214;215; V6T2-LABEL: unsigned_sat_lower_upper_2:216; V6T2: @ %bb.0: @ %entry217; V6T2-NEXT: movw r1, #65535218; V6T2-NEXT: movt r1, #127219; V6T2-NEXT: cmp r0, r1220; V6T2-NEXT: movlt r1, r0221; V6T2-NEXT: bic r0, r1, r1, asr #31222; V6T2-NEXT: bx lr223entry:224 %0 = icmp slt i32 %x, 8388607225 %saturateUp = select i1 %0, i32 %x, i32 8388607226 %1 = icmp sgt i32 %saturateUp, 0227 %saturateLow = select i1 %1, i32 %saturateUp, i32 0228 ret i32 %saturateLow229}230 231; x < k ? (x < 0 ? 0 : x) : k232define i32 @unsigned_sat_upper_lower_1(i32 %x) #0 {233; V4T-LABEL: unsigned_sat_upper_lower_1:234; V4T: @ %bb.0: @ %entry235; V4T-NEXT: bic r1, r0, r0, asr #31236; V4T-NEXT: ldr r0, .LCPI5_0237; V4T-NEXT: cmp r1, r0238; V4T-NEXT: movlt r0, r1239; V4T-NEXT: bx lr240; V4T-NEXT: .p2align 2241; V4T-NEXT: @ %bb.1:242; V4T-NEXT: .LCPI5_0:243; V4T-NEXT: .long 8388607 @ 0x7fffff244;245; V6-LABEL: unsigned_sat_upper_lower_1:246; V6: @ %bb.0: @ %entry247; V6-NEXT: bic r1, r0, r0, asr #31248; V6-NEXT: ldr r0, .LCPI5_0249; V6-NEXT: cmp r1, r0250; V6-NEXT: movlt r0, r1251; V6-NEXT: bx lr252; V6-NEXT: .p2align 2253; V6-NEXT: @ %bb.1:254; V6-NEXT: .LCPI5_0:255; V6-NEXT: .long 8388607 @ 0x7fffff256;257; V6T2-LABEL: unsigned_sat_upper_lower_1:258; V6T2: @ %bb.0: @ %entry259; V6T2-NEXT: bic r1, r0, r0, asr #31260; V6T2-NEXT: movw r0, #65535261; V6T2-NEXT: movt r0, #127262; V6T2-NEXT: cmp r1, r0263; V6T2-NEXT: movlt r0, r1264; V6T2-NEXT: bx lr265entry:266 %0 = icmp sgt i32 %x, 0267 %saturateLow = select i1 %0, i32 %x, i32 0268 %1 = icmp slt i32 %saturateLow, 8388607269 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607270 ret i32 %saturateUp271}272 273; x > k ? k : (x < 0 ? 0 : x)274define i32 @unsigned_sat_upper_lower_2(i32 %x) #0 {275; V4T-LABEL: unsigned_sat_upper_lower_2:276; V4T: @ %bb.0: @ %entry277; V4T-NEXT: bic r1, r0, r0, asr #31278; V4T-NEXT: ldr r0, .LCPI6_0279; V4T-NEXT: cmp r1, r0280; V4T-NEXT: movlt r0, r1281; V4T-NEXT: bx lr282; V4T-NEXT: .p2align 2283; V4T-NEXT: @ %bb.1:284; V4T-NEXT: .LCPI6_0:285; V4T-NEXT: .long 8388607 @ 0x7fffff286;287; V6-LABEL: unsigned_sat_upper_lower_2:288; V6: @ %bb.0: @ %entry289; V6-NEXT: bic r1, r0, r0, asr #31290; V6-NEXT: ldr r0, .LCPI6_0291; V6-NEXT: cmp r1, r0292; V6-NEXT: movlt r0, r1293; V6-NEXT: bx lr294; V6-NEXT: .p2align 2295; V6-NEXT: @ %bb.1:296; V6-NEXT: .LCPI6_0:297; V6-NEXT: .long 8388607 @ 0x7fffff298;299; V6T2-LABEL: unsigned_sat_upper_lower_2:300; V6T2: @ %bb.0: @ %entry301; V6T2-NEXT: bic r1, r0, r0, asr #31302; V6T2-NEXT: movw r0, #65535303; V6T2-NEXT: movt r0, #127304; V6T2-NEXT: cmp r1, r0305; V6T2-NEXT: movlt r0, r1306; V6T2-NEXT: bx lr307entry:308 %0 = icmp sgt i32 %x, 0309 %saturateLow = select i1 %0, i32 %x, i32 0310 %1 = icmp slt i32 %saturateLow, 8388607311 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607312 ret i32 %saturateUp313}314 315; k < x ? k : (x > 0 ? x : 0)316define i32 @unsigned_sat_upper_lower_3(i32 %x) #0 {317; V4T-LABEL: unsigned_sat_upper_lower_3:318; V4T: @ %bb.0: @ %entry319; V4T-NEXT: bic r1, r0, r0, asr #31320; V4T-NEXT: ldr r0, .LCPI7_0321; V4T-NEXT: cmp r1, r0322; V4T-NEXT: movlt r0, r1323; V4T-NEXT: bx lr324; V4T-NEXT: .p2align 2325; V4T-NEXT: @ %bb.1:326; V4T-NEXT: .LCPI7_0:327; V4T-NEXT: .long 8388607 @ 0x7fffff328;329; V6-LABEL: unsigned_sat_upper_lower_3:330; V6: @ %bb.0: @ %entry331; V6-NEXT: bic r1, r0, r0, asr #31332; V6-NEXT: ldr r0, .LCPI7_0333; V6-NEXT: cmp r1, r0334; V6-NEXT: movlt r0, r1335; V6-NEXT: bx lr336; V6-NEXT: .p2align 2337; V6-NEXT: @ %bb.1:338; V6-NEXT: .LCPI7_0:339; V6-NEXT: .long 8388607 @ 0x7fffff340;341; V6T2-LABEL: unsigned_sat_upper_lower_3:342; V6T2: @ %bb.0: @ %entry343; V6T2-NEXT: bic r1, r0, r0, asr #31344; V6T2-NEXT: movw r0, #65535345; V6T2-NEXT: movt r0, #127346; V6T2-NEXT: cmp r1, r0347; V6T2-NEXT: movlt r0, r1348; V6T2-NEXT: bx lr349entry:350 %cmpLow = icmp sgt i32 %x, 0351 %saturateLow = select i1 %cmpLow, i32 %x, i32 0352 %0 = icmp slt i32 %saturateLow, 8388607353 %saturateUp = select i1 %0, i32 %saturateLow, i32 8388607354 ret i32 %saturateUp355}356 357;358; The following tests check for patterns that should not transform359; into USAT but are similar enough that could confuse the selector.360;361; x > k ? k : (x > 0 ? 0 : x)362; First condition upper-saturates, second doesn't lower-saturate.363define i32 @no_unsigned_sat_missing_lower(i32 %x) #0 {364; V4T-LABEL: no_unsigned_sat_missing_lower:365; V4T: @ %bb.0: @ %entry366; V4T-NEXT: ldr r1, .LCPI8_0367; V4T-NEXT: cmp r0, #8388608368; V4T-NEXT: andlt r1, r0, r0, asr #31369; V4T-NEXT: mov r0, r1370; V4T-NEXT: bx lr371; V4T-NEXT: .p2align 2372; V4T-NEXT: @ %bb.1:373; V4T-NEXT: .LCPI8_0:374; V4T-NEXT: .long 8388607 @ 0x7fffff375;376; V6-LABEL: no_unsigned_sat_missing_lower:377; V6: @ %bb.0: @ %entry378; V6-NEXT: ldr r1, .LCPI8_0379; V6-NEXT: cmp r0, #8388608380; V6-NEXT: andlt r1, r0, r0, asr #31381; V6-NEXT: mov r0, r1382; V6-NEXT: bx lr383; V6-NEXT: .p2align 2384; V6-NEXT: @ %bb.1:385; V6-NEXT: .LCPI8_0:386; V6-NEXT: .long 8388607 @ 0x7fffff387;388; V6T2-LABEL: no_unsigned_sat_missing_lower:389; V6T2: @ %bb.0: @ %entry390; V6T2-NEXT: and r1, r0, r0, asr #31391; V6T2-NEXT: cmp r0, #8388608392; V6T2-NEXT: movwge r1, #65535393; V6T2-NEXT: movtge r1, #127394; V6T2-NEXT: mov r0, r1395; V6T2-NEXT: bx lr396entry:397 %cmpUp = icmp sgt i32 %x, 8388607398 %0 = icmp slt i32 %x, 0399 %saturateLow = select i1 %0, i32 %x, i32 0400 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow401 ret i32 %saturateUp402}403 404; x < k ? k : (x < 0 ? 0 : x)405; Second condition lower-saturates, first doesn't upper-saturate.406define i32 @no_unsigned_sat_missing_upper(i32 %x) #0 {407; V4T-LABEL: no_unsigned_sat_missing_upper:408; V4T: @ %bb.0: @ %entry409; V4T-NEXT: ldr r1, .LCPI9_0410; V4T-NEXT: cmp r0, r1411; V4T-NEXT: bicge r1, r0, r0, asr #31412; V4T-NEXT: mov r0, r1413; V4T-NEXT: bx lr414; V4T-NEXT: .p2align 2415; V4T-NEXT: @ %bb.1:416; V4T-NEXT: .LCPI9_0:417; V4T-NEXT: .long 8388607 @ 0x7fffff418;419; V6-LABEL: no_unsigned_sat_missing_upper:420; V6: @ %bb.0: @ %entry421; V6-NEXT: ldr r1, .LCPI9_0422; V6-NEXT: cmp r0, r1423; V6-NEXT: bicge r1, r0, r0, asr #31424; V6-NEXT: mov r0, r1425; V6-NEXT: bx lr426; V6-NEXT: .p2align 2427; V6-NEXT: @ %bb.1:428; V6-NEXT: .LCPI9_0:429; V6-NEXT: .long 8388607 @ 0x7fffff430;431; V6T2-LABEL: no_unsigned_sat_missing_upper:432; V6T2: @ %bb.0: @ %entry433; V6T2-NEXT: movw r2, #65535434; V6T2-NEXT: bic r1, r0, r0, asr #31435; V6T2-NEXT: movt r2, #127436; V6T2-NEXT: cmp r0, r2437; V6T2-NEXT: movwlt r1, #65535438; V6T2-NEXT: movtlt r1, #127439; V6T2-NEXT: mov r0, r1440; V6T2-NEXT: bx lr441entry:442 %cmpUp = icmp slt i32 %x, 8388607443 %0 = icmp sgt i32 %x, 0444 %saturateLow = select i1 %0, i32 %x, i32 0445 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow446 ret i32 %saturateUp447}448 449; Lower constant is different in the select and in the compare450define i32 @no_unsigned_sat_incorrect_constant(i32 %x) #0 {451; V4T-LABEL: no_unsigned_sat_incorrect_constant:452; V4T: @ %bb.0: @ %entry453; V4T-NEXT: orr r1, r0, r0, asr #31454; V4T-NEXT: ldr r0, .LCPI10_0455; V4T-NEXT: cmp r1, r0456; V4T-NEXT: movlt r0, r1457; V4T-NEXT: bx lr458; V4T-NEXT: .p2align 2459; V4T-NEXT: @ %bb.1:460; V4T-NEXT: .LCPI10_0:461; V4T-NEXT: .long 8388607 @ 0x7fffff462;463; V6-LABEL: no_unsigned_sat_incorrect_constant:464; V6: @ %bb.0: @ %entry465; V6-NEXT: orr r1, r0, r0, asr #31466; V6-NEXT: ldr r0, .LCPI10_0467; V6-NEXT: cmp r1, r0468; V6-NEXT: movlt r0, r1469; V6-NEXT: bx lr470; V6-NEXT: .p2align 2471; V6-NEXT: @ %bb.1:472; V6-NEXT: .LCPI10_0:473; V6-NEXT: .long 8388607 @ 0x7fffff474;475; V6T2-LABEL: no_unsigned_sat_incorrect_constant:476; V6T2: @ %bb.0: @ %entry477; V6T2-NEXT: orr r1, r0, r0, asr #31478; V6T2-NEXT: movw r0, #65535479; V6T2-NEXT: movt r0, #127480; V6T2-NEXT: cmp r1, r0481; V6T2-NEXT: movlt r0, r1482; V6T2-NEXT: bx lr483entry:484 %cmpLow.inv = icmp sgt i32 %x, -1485 %saturateLow = select i1 %cmpLow.inv, i32 %x, i32 -1486 %0 = icmp slt i32 %saturateLow, 8388607487 %saturateUp = select i1 %0, i32 %saturateLow, i32 8388607488 ret i32 %saturateUp489}490 491; The interval is [0, k] but k+1 is not a power of 2492define i32 @no_unsigned_sat_incorrect_constant2(i32 %x) #0 {493; V4T-LABEL: no_unsigned_sat_incorrect_constant2:494; V4T: @ %bb.0: @ %entry495; V4T-NEXT: bic r1, r0, r0, asr #31496; V4T-NEXT: mov r0, #1497; V4T-NEXT: orr r0, r0, #8388608498; V4T-NEXT: cmp r1, #8388608499; V4T-NEXT: movle r0, r1500; V4T-NEXT: bx lr501;502; V6-LABEL: no_unsigned_sat_incorrect_constant2:503; V6: @ %bb.0: @ %entry504; V6-NEXT: bic r1, r0, r0, asr #31505; V6-NEXT: mov r0, #1506; V6-NEXT: orr r0, r0, #8388608507; V6-NEXT: cmp r1, #8388608508; V6-NEXT: movle r0, r1509; V6-NEXT: bx lr510;511; V6T2-LABEL: no_unsigned_sat_incorrect_constant2:512; V6T2: @ %bb.0: @ %entry513; V6T2-NEXT: bic r1, r0, r0, asr #31514; V6T2-NEXT: movw r0, #1515; V6T2-NEXT: movt r0, #128516; V6T2-NEXT: cmp r1, #8388608517; V6T2-NEXT: movle r0, r1518; V6T2-NEXT: bx lr519entry:520 %0 = icmp sgt i32 %x, 0521 %saturateLow = select i1 %0, i32 %x, i32 0522 %1 = icmp slt i32 %saturateLow, 8388609523 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388609524 ret i32 %saturateUp525}526 527; The interval is not [0, k]528define i32 @no_unsigned_sat_incorrect_interval(i32 %x) #0 {529; V4T-LABEL: no_unsigned_sat_incorrect_interval:530; V4T: @ %bb.0: @ %entry531; V4T-NEXT: ldr r1, .LCPI12_0532; V4T-NEXT: cmn r0, #4533; V4T-NEXT: mvnle r0, #3534; V4T-NEXT: cmp r0, r1535; V4T-NEXT: movge r0, r1536; V4T-NEXT: bx lr537; V4T-NEXT: .p2align 2538; V4T-NEXT: @ %bb.1:539; V4T-NEXT: .LCPI12_0:540; V4T-NEXT: .long 8388607 @ 0x7fffff541;542; V6-LABEL: no_unsigned_sat_incorrect_interval:543; V6: @ %bb.0: @ %entry544; V6-NEXT: ldr r1, .LCPI12_0545; V6-NEXT: cmn r0, #4546; V6-NEXT: mvnle r0, #3547; V6-NEXT: cmp r0, r1548; V6-NEXT: movge r0, r1549; V6-NEXT: bx lr550; V6-NEXT: .p2align 2551; V6-NEXT: @ %bb.1:552; V6-NEXT: .LCPI12_0:553; V6-NEXT: .long 8388607 @ 0x7fffff554;555; V6T2-LABEL: no_unsigned_sat_incorrect_interval:556; V6T2: @ %bb.0: @ %entry557; V6T2-NEXT: cmn r0, #4558; V6T2-NEXT: movw r1, #65535559; V6T2-NEXT: mvnle r0, #3560; V6T2-NEXT: movt r1, #127561; V6T2-NEXT: cmp r0, r1562; V6T2-NEXT: movge r0, r1563; V6T2-NEXT: bx lr564entry:565 %0 = icmp sgt i32 %x, -4566 %saturateLow = select i1 %0, i32 %x, i32 -4567 %1 = icmp slt i32 %saturateLow, 8388607568 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607569 ret i32 %saturateUp570}571 572; The returned value (y) is not the same as the tested value (x).573define i32 @no_unsigned_sat_incorrect_return(i32 %x, i32 %y) #0 {574; V4T-LABEL: no_unsigned_sat_incorrect_return:575; V4T: @ %bb.0: @ %entry576; V4T-NEXT: cmp r0, #0577; V4T-NEXT: ldr r2, .LCPI13_0578; V4T-NEXT: movmi r1, #0579; V4T-NEXT: cmp r0, #8388608580; V4T-NEXT: movlt r2, r1581; V4T-NEXT: mov r0, r2582; V4T-NEXT: bx lr583; V4T-NEXT: .p2align 2584; V4T-NEXT: @ %bb.1:585; V4T-NEXT: .LCPI13_0:586; V4T-NEXT: .long 8388607 @ 0x7fffff587;588; V6-LABEL: no_unsigned_sat_incorrect_return:589; V6: @ %bb.0: @ %entry590; V6-NEXT: cmp r0, #0591; V6-NEXT: ldr r2, .LCPI13_0592; V6-NEXT: movmi r1, #0593; V6-NEXT: cmp r0, #8388608594; V6-NEXT: movlt r2, r1595; V6-NEXT: mov r0, r2596; V6-NEXT: bx lr597; V6-NEXT: .p2align 2598; V6-NEXT: @ %bb.1:599; V6-NEXT: .LCPI13_0:600; V6-NEXT: .long 8388607 @ 0x7fffff601;602; V6T2-LABEL: no_unsigned_sat_incorrect_return:603; V6T2: @ %bb.0: @ %entry604; V6T2-NEXT: cmp r0, #0605; V6T2-NEXT: movwmi r1, #0606; V6T2-NEXT: cmp r0, #8388608607; V6T2-NEXT: movwge r1, #65535608; V6T2-NEXT: movtge r1, #127609; V6T2-NEXT: mov r0, r1610; V6T2-NEXT: bx lr611entry:612 %cmpUp = icmp sgt i32 %x, 8388607613 %cmpLow = icmp slt i32 %x, 0614 %saturateLow = select i1 %cmpLow, i32 0, i32 %y615 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow616 ret i32 %saturateUp617}618 619; One of the values in a compare (y) is not the same as the rest620; of the compare and select values (x).621define i32 @no_unsigned_sat_incorrect_compare(i32 %x, i32 %y) #0 {622; V4T-LABEL: no_unsigned_sat_incorrect_compare:623; V4T: @ %bb.0: @ %entry624; V4T-NEXT: cmp r1, #0625; V4T-NEXT: mov r2, r0626; V4T-NEXT: movmi r2, #0627; V4T-NEXT: ldr r1, .LCPI14_0628; V4T-NEXT: cmp r0, #8388608629; V4T-NEXT: movlt r1, r2630; V4T-NEXT: mov r0, r1631; V4T-NEXT: bx lr632; V4T-NEXT: .p2align 2633; V4T-NEXT: @ %bb.1:634; V4T-NEXT: .LCPI14_0:635; V4T-NEXT: .long 8388607 @ 0x7fffff636;637; V6-LABEL: no_unsigned_sat_incorrect_compare:638; V6: @ %bb.0: @ %entry639; V6-NEXT: cmp r1, #0640; V6-NEXT: mov r2, r0641; V6-NEXT: movmi r2, #0642; V6-NEXT: ldr r1, .LCPI14_0643; V6-NEXT: cmp r0, #8388608644; V6-NEXT: movlt r1, r2645; V6-NEXT: mov r0, r1646; V6-NEXT: bx lr647; V6-NEXT: .p2align 2648; V6-NEXT: @ %bb.1:649; V6-NEXT: .LCPI14_0:650; V6-NEXT: .long 8388607 @ 0x7fffff651;652; V6T2-LABEL: no_unsigned_sat_incorrect_compare:653; V6T2: @ %bb.0: @ %entry654; V6T2-NEXT: cmp r1, #0655; V6T2-NEXT: mov r1, r0656; V6T2-NEXT: movwmi r1, #0657; V6T2-NEXT: cmp r0, #8388608658; V6T2-NEXT: movwge r1, #65535659; V6T2-NEXT: movtge r1, #127660; V6T2-NEXT: mov r0, r1661; V6T2-NEXT: bx lr662entry:663 %cmpUp = icmp sgt i32 %x, 8388607664 %cmpLow = icmp slt i32 %y, 0665 %saturateLow = select i1 %cmpLow, i32 0, i32 %x666 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow667 ret i32 %saturateUp668}669 670define i32 @mm_unsigned_sat_base_32bit(i32 %x) {671; V4T-LABEL: mm_unsigned_sat_base_32bit:672; V4T: @ %bb.0: @ %entry673; V4T-NEXT: ldr r1, .LCPI15_0674; V4T-NEXT: cmp r0, r1675; V4T-NEXT: movlt r1, r0676; V4T-NEXT: bic r0, r1, r1, asr #31677; V4T-NEXT: bx lr678; V4T-NEXT: .p2align 2679; V4T-NEXT: @ %bb.1:680; V4T-NEXT: .LCPI15_0:681; V4T-NEXT: .long 8388607 @ 0x7fffff682;683; V6-LABEL: mm_unsigned_sat_base_32bit:684; V6: @ %bb.0: @ %entry685; V6-NEXT: usat r0, #23, r0686; V6-NEXT: bx lr687;688; V6T2-LABEL: mm_unsigned_sat_base_32bit:689; V6T2: @ %bb.0: @ %entry690; V6T2-NEXT: usat r0, #23, r0691; V6T2-NEXT: bx lr692entry:693 %0 = call i32 @llvm.smin.i32(i32 %x, i32 8388607)694 %1 = call i32 @llvm.smax.i32(i32 %0, i32 0)695 ret i32 %1696}697 698define i16 @mm_unsigned_sat_base_16bit(i16 %x) {699; V4T-LABEL: mm_unsigned_sat_base_16bit:700; V4T: @ %bb.0: @ %entry701; V4T-NEXT: mov r2, #255702; V4T-NEXT: lsl r0, r0, #16703; V4T-NEXT: orr r2, r2, #1792704; V4T-NEXT: asr r1, r0, #16705; V4T-NEXT: cmp r1, r2706; V4T-NEXT: asrlt r2, r0, #16707; V4T-NEXT: bic r0, r2, r2, asr #31708; V4T-NEXT: bx lr709;710; V6-LABEL: mm_unsigned_sat_base_16bit:711; V6: @ %bb.0: @ %entry712; V6-NEXT: sxth r0, r0713; V6-NEXT: usat r0, #11, r0714; V6-NEXT: bx lr715;716; V6T2-LABEL: mm_unsigned_sat_base_16bit:717; V6T2: @ %bb.0: @ %entry718; V6T2-NEXT: sxth r0, r0719; V6T2-NEXT: usat r0, #11, r0720; V6T2-NEXT: bx lr721entry:722 %0 = call i16 @llvm.smin.i16(i16 %x, i16 2047)723 %1 = call i16 @llvm.smax.i16(i16 %0, i16 0)724 ret i16 %1725}726 727define i8 @mm_unsigned_sat_base_8bit(i8 %x) {728; V4T-LABEL: mm_unsigned_sat_base_8bit:729; V4T: @ %bb.0: @ %entry730; V4T-NEXT: lsl r0, r0, #24731; V4T-NEXT: mov r2, #31732; V4T-NEXT: asr r1, r0, #24733; V4T-NEXT: cmp r1, #31734; V4T-NEXT: asrlt r2, r0, #24735; V4T-NEXT: bic r0, r2, r2, asr #31736; V4T-NEXT: bx lr737;738; V6-LABEL: mm_unsigned_sat_base_8bit:739; V6: @ %bb.0: @ %entry740; V6-NEXT: sxtb r0, r0741; V6-NEXT: usat r0, #5, r0742; V6-NEXT: bx lr743;744; V6T2-LABEL: mm_unsigned_sat_base_8bit:745; V6T2: @ %bb.0: @ %entry746; V6T2-NEXT: sxtb r0, r0747; V6T2-NEXT: usat r0, #5, r0748; V6T2-NEXT: bx lr749entry:750 %0 = call i8 @llvm.smin.i8(i8 %x, i8 31)751 %1 = call i8 @llvm.smax.i8(i8 %0, i8 0)752 ret i8 %1753}754 755define i32 @mm_unsigned_sat_lower_upper_1(i32 %x) {756; V4T-LABEL: mm_unsigned_sat_lower_upper_1:757; V4T: @ %bb.0: @ %entry758; V4T-NEXT: ldr r1, .LCPI18_0759; V4T-NEXT: cmp r0, r1760; V4T-NEXT: movlt r1, r0761; V4T-NEXT: bic r0, r1, r1, asr #31762; V4T-NEXT: bx lr763; V4T-NEXT: .p2align 2764; V4T-NEXT: @ %bb.1:765; V4T-NEXT: .LCPI18_0:766; V4T-NEXT: .long 8388607 @ 0x7fffff767;768; V6-LABEL: mm_unsigned_sat_lower_upper_1:769; V6: @ %bb.0: @ %entry770; V6-NEXT: usat r0, #23, r0771; V6-NEXT: bx lr772;773; V6T2-LABEL: mm_unsigned_sat_lower_upper_1:774; V6T2: @ %bb.0: @ %entry775; V6T2-NEXT: usat r0, #23, r0776; V6T2-NEXT: bx lr777entry:778 %0 = call i32 @llvm.smin.i32(i32 %x, i32 8388607)779 %1 = call i32 @llvm.smax.i32(i32 %0, i32 0)780 ret i32 %1781}782 783define i32 @mm_unsigned_sat_lower_upper_2(i32 %x) {784; V4T-LABEL: mm_unsigned_sat_lower_upper_2:785; V4T: @ %bb.0: @ %entry786; V4T-NEXT: ldr r1, .LCPI19_0787; V4T-NEXT: cmp r0, r1788; V4T-NEXT: movlt r1, r0789; V4T-NEXT: bic r0, r1, r1, asr #31790; V4T-NEXT: bx lr791; V4T-NEXT: .p2align 2792; V4T-NEXT: @ %bb.1:793; V4T-NEXT: .LCPI19_0:794; V4T-NEXT: .long 8388607 @ 0x7fffff795;796; V6-LABEL: mm_unsigned_sat_lower_upper_2:797; V6: @ %bb.0: @ %entry798; V6-NEXT: usat r0, #23, r0799; V6-NEXT: bx lr800;801; V6T2-LABEL: mm_unsigned_sat_lower_upper_2:802; V6T2: @ %bb.0: @ %entry803; V6T2-NEXT: usat r0, #23, r0804; V6T2-NEXT: bx lr805entry:806 %0 = call i32 @llvm.smin.i32(i32 %x, i32 8388607)807 %1 = call i32 @llvm.smax.i32(i32 %0, i32 0)808 ret i32 %1809}810 811define i32 @mm_unsigned_sat_upper_lower_1(i32 %x) {812; V4T-LABEL: mm_unsigned_sat_upper_lower_1:813; V4T: @ %bb.0: @ %entry814; V4T-NEXT: bic r1, r0, r0, asr #31815; V4T-NEXT: ldr r0, .LCPI20_0816; V4T-NEXT: cmp r1, r0817; V4T-NEXT: movlt r0, r1818; V4T-NEXT: bx lr819; V4T-NEXT: .p2align 2820; V4T-NEXT: @ %bb.1:821; V4T-NEXT: .LCPI20_0:822; V4T-NEXT: .long 8388607 @ 0x7fffff823;824; V6-LABEL: mm_unsigned_sat_upper_lower_1:825; V6: @ %bb.0: @ %entry826; V6-NEXT: usat r0, #23, r0827; V6-NEXT: bx lr828;829; V6T2-LABEL: mm_unsigned_sat_upper_lower_1:830; V6T2: @ %bb.0: @ %entry831; V6T2-NEXT: usat r0, #23, r0832; V6T2-NEXT: bx lr833entry:834 %0 = call i32 @llvm.smax.i32(i32 %x, i32 0)835 %1 = call i32 @llvm.umin.i32(i32 %0, i32 8388607)836 ret i32 %1837}838 839define i32 @mm_unsigned_sat_upper_lower_2(i32 %x) {840; V4T-LABEL: mm_unsigned_sat_upper_lower_2:841; V4T: @ %bb.0: @ %entry842; V4T-NEXT: bic r1, r0, r0, asr #31843; V4T-NEXT: ldr r0, .LCPI21_0844; V4T-NEXT: cmp r1, r0845; V4T-NEXT: movlt r0, r1846; V4T-NEXT: bx lr847; V4T-NEXT: .p2align 2848; V4T-NEXT: @ %bb.1:849; V4T-NEXT: .LCPI21_0:850; V4T-NEXT: .long 8388607 @ 0x7fffff851;852; V6-LABEL: mm_unsigned_sat_upper_lower_2:853; V6: @ %bb.0: @ %entry854; V6-NEXT: usat r0, #23, r0855; V6-NEXT: bx lr856;857; V6T2-LABEL: mm_unsigned_sat_upper_lower_2:858; V6T2: @ %bb.0: @ %entry859; V6T2-NEXT: usat r0, #23, r0860; V6T2-NEXT: bx lr861entry:862 %0 = call i32 @llvm.smax.i32(i32 %x, i32 0)863 %1 = call i32 @llvm.umin.i32(i32 %0, i32 8388607)864 ret i32 %1865}866 867define i32 @mm_unsigned_sat_upper_lower_3(i32 %x) {868; V4T-LABEL: mm_unsigned_sat_upper_lower_3:869; V4T: @ %bb.0: @ %entry870; V4T-NEXT: bic r1, r0, r0, asr #31871; V4T-NEXT: ldr r0, .LCPI22_0872; V4T-NEXT: cmp r1, r0873; V4T-NEXT: movlt r0, r1874; V4T-NEXT: bx lr875; V4T-NEXT: .p2align 2876; V4T-NEXT: @ %bb.1:877; V4T-NEXT: .LCPI22_0:878; V4T-NEXT: .long 8388607 @ 0x7fffff879;880; V6-LABEL: mm_unsigned_sat_upper_lower_3:881; V6: @ %bb.0: @ %entry882; V6-NEXT: usat r0, #23, r0883; V6-NEXT: bx lr884;885; V6T2-LABEL: mm_unsigned_sat_upper_lower_3:886; V6T2: @ %bb.0: @ %entry887; V6T2-NEXT: usat r0, #23, r0888; V6T2-NEXT: bx lr889entry:890 %0 = call i32 @llvm.smax.i32(i32 %x, i32 0)891 %1 = call i32 @llvm.umin.i32(i32 %0, i32 8388607)892 ret i32 %1893}894 895define i32 @mm_no_unsigned_sat_incorrect_constant(i32 %x) {896; V4T-LABEL: mm_no_unsigned_sat_incorrect_constant:897; V4T: @ %bb.0: @ %entry898; V4T-NEXT: orr r1, r0, r0, asr #31899; V4T-NEXT: ldr r0, .LCPI23_0900; V4T-NEXT: cmp r1, r0901; V4T-NEXT: movlt r0, r1902; V4T-NEXT: bx lr903; V4T-NEXT: .p2align 2904; V4T-NEXT: @ %bb.1:905; V4T-NEXT: .LCPI23_0:906; V4T-NEXT: .long 8388607 @ 0x7fffff907;908; V6-LABEL: mm_no_unsigned_sat_incorrect_constant:909; V6: @ %bb.0: @ %entry910; V6-NEXT: orr r1, r0, r0, asr #31911; V6-NEXT: ldr r0, .LCPI23_0912; V6-NEXT: cmp r1, r0913; V6-NEXT: movlt r0, r1914; V6-NEXT: bx lr915; V6-NEXT: .p2align 2916; V6-NEXT: @ %bb.1:917; V6-NEXT: .LCPI23_0:918; V6-NEXT: .long 8388607 @ 0x7fffff919;920; V6T2-LABEL: mm_no_unsigned_sat_incorrect_constant:921; V6T2: @ %bb.0: @ %entry922; V6T2-NEXT: orr r1, r0, r0, asr #31923; V6T2-NEXT: movw r0, #65535924; V6T2-NEXT: movt r0, #127925; V6T2-NEXT: cmp r1, r0926; V6T2-NEXT: movlt r0, r1927; V6T2-NEXT: bx lr928entry:929 %0 = call i32 @llvm.smax.i32(i32 %x, i32 -1)930 %1 = call i32 @llvm.smin.i32(i32 %0, i32 8388607)931 ret i32 %1932}933 934define i32 @mm_no_unsigned_sat_incorrect_constant2(i32 %x) {935; V4T-LABEL: mm_no_unsigned_sat_incorrect_constant2:936; V4T: @ %bb.0: @ %entry937; V4T-NEXT: bic r1, r0, r0, asr #31938; V4T-NEXT: mov r0, #1939; V4T-NEXT: orr r0, r0, #8388608940; V4T-NEXT: cmp r1, #8388608941; V4T-NEXT: movle r0, r1942; V4T-NEXT: bx lr943;944; V6-LABEL: mm_no_unsigned_sat_incorrect_constant2:945; V6: @ %bb.0: @ %entry946; V6-NEXT: bic r1, r0, r0, asr #31947; V6-NEXT: mov r0, #1948; V6-NEXT: orr r0, r0, #8388608949; V6-NEXT: cmp r1, #8388608950; V6-NEXT: movle r0, r1951; V6-NEXT: bx lr952;953; V6T2-LABEL: mm_no_unsigned_sat_incorrect_constant2:954; V6T2: @ %bb.0: @ %entry955; V6T2-NEXT: bic r1, r0, r0, asr #31956; V6T2-NEXT: movw r0, #1957; V6T2-NEXT: movt r0, #128958; V6T2-NEXT: cmp r1, #8388608959; V6T2-NEXT: movle r0, r1960; V6T2-NEXT: bx lr961entry:962 %0 = call i32 @llvm.smax.i32(i32 %x, i32 0)963 %1 = call i32 @llvm.umin.i32(i32 %0, i32 8388609)964 ret i32 %1965}966 967define i32 @mm_no_unsigned_sat_incorrect_interval(i32 %x) {968; V4T-LABEL: mm_no_unsigned_sat_incorrect_interval:969; V4T: @ %bb.0: @ %entry970; V4T-NEXT: ldr r1, .LCPI25_0971; V4T-NEXT: cmn r0, #4972; V4T-NEXT: mvnle r0, #3973; V4T-NEXT: cmp r0, r1974; V4T-NEXT: movge r0, r1975; V4T-NEXT: bx lr976; V4T-NEXT: .p2align 2977; V4T-NEXT: @ %bb.1:978; V4T-NEXT: .LCPI25_0:979; V4T-NEXT: .long 8388607 @ 0x7fffff980;981; V6-LABEL: mm_no_unsigned_sat_incorrect_interval:982; V6: @ %bb.0: @ %entry983; V6-NEXT: ldr r1, .LCPI25_0984; V6-NEXT: cmn r0, #4985; V6-NEXT: mvnle r0, #3986; V6-NEXT: cmp r0, r1987; V6-NEXT: movge r0, r1988; V6-NEXT: bx lr989; V6-NEXT: .p2align 2990; V6-NEXT: @ %bb.1:991; V6-NEXT: .LCPI25_0:992; V6-NEXT: .long 8388607 @ 0x7fffff993;994; V6T2-LABEL: mm_no_unsigned_sat_incorrect_interval:995; V6T2: @ %bb.0: @ %entry996; V6T2-NEXT: cmn r0, #4997; V6T2-NEXT: movw r1, #65535998; V6T2-NEXT: mvnle r0, #3999; V6T2-NEXT: movt r1, #1271000; V6T2-NEXT: cmp r0, r11001; V6T2-NEXT: movge r0, r11002; V6T2-NEXT: bx lr1003entry:1004 %0 = call i32 @llvm.smax.i32(i32 %x, i32 -4)1005 %1 = call i32 @llvm.smin.i32(i32 %0, i32 8388607)1006 ret i32 %11007}1008 1009define i32 @test_umin_smax_usat(i32 %x) {1010; V4T-LABEL: test_umin_smax_usat:1011; V4T: @ %bb.0: @ %entry1012; V4T-NEXT: bic r0, r0, r0, asr #311013; V4T-NEXT: cmp r0, #2551014; V4T-NEXT: movge r0, #2551015; V4T-NEXT: bx lr1016;1017; V6-LABEL: test_umin_smax_usat:1018; V6: @ %bb.0: @ %entry1019; V6-NEXT: usat r0, #8, r01020; V6-NEXT: bx lr1021;1022; V6T2-LABEL: test_umin_smax_usat:1023; V6T2: @ %bb.0: @ %entry1024; V6T2-NEXT: usat r0, #8, r01025; V6T2-NEXT: bx lr1026entry:1027 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 0)1028 %v2 = tail call i32 @llvm.umin.i32(i32 %v1, i32 255)1029 ret i32 %v21030}1031 1032declare i32 @llvm.smin.i32(i32, i32)1033declare i32 @llvm.smax.i32(i32, i32)1034declare i16 @llvm.smin.i16(i16, i16)1035declare i16 @llvm.smax.i16(i16, i16)1036declare i8 @llvm.smin.i8(i8, i8)1037declare i8 @llvm.smax.i8(i8, i8)1038declare i32 @llvm.umin.i32(i32, i32)1039