1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=armv4t-eabi %s -o - | FileCheck %s --check-prefix=V4T 3; RUN: llc -mtriple=armv6-eabi %s -o - | FileCheck %s --check-prefix=V6 4; RUN: llc -mtriple=armv6t2-eabi %s -o - | FileCheck %s --check-prefix=V6T2 5 6; Check for several conditions that should result in USAT. 7; For example, the base test is equivalent to 8; x < 0 ? 0 : (x > k ? k : x) in C. All patterns that bound x 9; to the interval [0, k] where k + 1 is a power of 2 can be 10; transformed into USAT. At the end there are some tests 11; checking that conditionals are not transformed if they don't 12; match the right pattern. 13 14; 15; Base tests with different bit widths 16; 17 18; x < 0 ? 0 : (x > k ? k : x) 19; 32-bit base test 20define i32 @unsigned_sat_base_32bit(i32 %x) #0 { 21; V4T-LABEL: unsigned_sat_base_32bit: 22; V4T: @ %bb.0: @ %entry 23; V4T-NEXT: ldr r1, .LCPI0_0 24; V4T-NEXT: cmp r0, r1 25; V4T-NEXT: movlt r1, r0 26; V4T-NEXT: bic r0, r1, r1, asr #31 27; V4T-NEXT: bx lr 28; V4T-NEXT: .p2align 2 29; V4T-NEXT: @ %bb.1: 30; V4T-NEXT: .LCPI0_0: 31; V4T-NEXT: .long 8388607 @ 0x7fffff 32; 33; V6-LABEL: unsigned_sat_base_32bit: 34; V6: @ %bb.0: @ %entry 35; V6-NEXT: usat r0, #23, r0 36; V6-NEXT: bx lr 37; 38; V6T2-LABEL: unsigned_sat_base_32bit: 39; V6T2: @ %bb.0: @ %entry 40; V6T2-NEXT: usat r0, #23, r0 41; V6T2-NEXT: bx lr 42entry: 43 %0 = icmp slt i32 %x, 8388607 44 %saturateUp = select i1 %0, i32 %x, i32 8388607 45 %1 = icmp sgt i32 %saturateUp, 0 46 %saturateLow = select i1 %1, i32 %saturateUp, i32 0 47 ret i32 %saturateLow 48} 49 50; x < 0 ? 0 : (x > k ? k : x) 51; 16-bit base test 52define i16 @unsigned_sat_base_16bit(i16 %x) #0 { 53; V4T-LABEL: unsigned_sat_base_16bit: 54; V4T: @ %bb.0: @ %entry 55; V4T-NEXT: lsl r1, r0, #16 56; V4T-NEXT: asr r2, r1, #16 57; V4T-NEXT: mov r1, #255 58; V4T-NEXT: orr r1, r1, #1792 59; V4T-NEXT: cmp r2, r1 60; V4T-NEXT: movlt r1, r0 61; V4T-NEXT: lsl r0, r1, #16 62; V4T-NEXT: asr r0, r0, #16 63; V4T-NEXT: cmp r0, #0 64; V4T-NEXT: movle r1, #0 65; V4T-NEXT: mov r0, r1 66; V4T-NEXT: bx lr 67; 68; V6-LABEL: unsigned_sat_base_16bit: 69; V6: @ %bb.0: @ %entry 70; V6-NEXT: mov r1, #255 71; V6-NEXT: sxth r2, r0 72; V6-NEXT: orr r1, r1, #1792 73; V6-NEXT: cmp r2, r1 74; V6-NEXT: movlt r1, r0 75; V6-NEXT: sxth r0, r1 76; V6-NEXT: cmp r0, #0 77; V6-NEXT: movle r1, #0 78; V6-NEXT: mov r0, r1 79; V6-NEXT: bx lr 80; 81; V6T2-LABEL: unsigned_sat_base_16bit: 82; V6T2: @ %bb.0: @ %entry 83; V6T2-NEXT: sxth r2, r0 84; V6T2-NEXT: movw r1, #2047 85; V6T2-NEXT: cmp r2, r1 86; V6T2-NEXT: movlt r1, r0 87; V6T2-NEXT: sxth r0, r1 88; V6T2-NEXT: cmp r0, #0 89; V6T2-NEXT: movle r1, #0 90; V6T2-NEXT: mov r0, r1 91; V6T2-NEXT: bx lr 92entry: 93 %0 = icmp slt i16 %x, 2047 94 %saturateUp = select i1 %0, i16 %x, i16 2047 95 %1 = icmp sgt i16 %saturateUp, 0 96 %saturateLow = select i1 %1, i16 %saturateUp, i16 0 97 ret i16 %saturateLow 98} 99 100; x < 0 ? 0 : (x > k ? k : x) 101; 8-bit base test 102define i8 @unsigned_sat_base_8bit(i8 %x) #0 { 103; V4T-LABEL: unsigned_sat_base_8bit: 104; V4T: @ %bb.0: @ %entry 105; V4T-NEXT: lsl r1, r0, #24 106; V4T-NEXT: asr r1, r1, #24 107; V4T-NEXT: cmp r1, #31 108; V4T-NEXT: movge r0, #31 109; V4T-NEXT: lsl r1, r0, #24 110; V4T-NEXT: asr r1, r1, #24 111; V4T-NEXT: cmp r1, #0 112; V4T-NEXT: movle r0, #0 113; V4T-NEXT: bx lr 114; 115; V6-LABEL: unsigned_sat_base_8bit: 116; V6: @ %bb.0: @ %entry 117; V6-NEXT: sxtb r1, r0 118; V6-NEXT: cmp r1, #31 119; V6-NEXT: movge r0, #31 120; V6-NEXT: sxtb r1, r0 121; V6-NEXT: cmp r1, #0 122; V6-NEXT: movle r0, #0 123; V6-NEXT: bx lr 124; 125; V6T2-LABEL: unsigned_sat_base_8bit: 126; V6T2: @ %bb.0: @ %entry 127; V6T2-NEXT: sxtb r1, r0 128; V6T2-NEXT: cmp r1, #31 129; V6T2-NEXT: movge r0, #31 130; V6T2-NEXT: sxtb r1, r0 131; V6T2-NEXT: cmp r1, #0 132; V6T2-NEXT: movle r0, #0 133; V6T2-NEXT: bx lr 134entry: 135 %0 = icmp slt i8 %x, 31 136 %saturateUp = select i1 %0, i8 %x, i8 31 137 %1 = icmp sgt i8 %saturateUp, 0 138 %saturateLow = select i1 %1, i8 %saturateUp, i8 0 139 ret i8 %saturateLow 140} 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 some 145; 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: @ %entry 151; V4T-NEXT: ldr r1, .LCPI3_0 152; V4T-NEXT: cmp r0, r1 153; V4T-NEXT: movlt r1, r0 154; V4T-NEXT: bic r0, r1, r1, asr #31 155; V4T-NEXT: bx lr 156; V4T-NEXT: .p2align 2 157; V4T-NEXT: @ %bb.1: 158; V4T-NEXT: .LCPI3_0: 159; V4T-NEXT: .long 8388607 @ 0x7fffff 160; 161; V6-LABEL: unsigned_sat_lower_upper_1: 162; V6: @ %bb.0: @ %entry 163; V6-NEXT: usat r0, #23, r0 164; V6-NEXT: bx lr 165; 166; V6T2-LABEL: unsigned_sat_lower_upper_1: 167; V6T2: @ %bb.0: @ %entry 168; V6T2-NEXT: usat r0, #23, r0 169; V6T2-NEXT: bx lr 170entry: 171 %cmpUp = icmp slt i32 %x, 8388607 172 %saturateUp = select i1 %cmpUp, i32 %x, i32 8388607 173 %0 = icmp sgt i32 %saturateUp, 0 174 %saturateLow = select i1 %0, i32 %saturateUp, i32 0 175 ret i32 %saturateLow 176} 177 178; x > 0 ? (x > k ? k : x) : 0 179define i32 @unsigned_sat_lower_upper_2(i32 %x) #0 { 180; V4T-LABEL: unsigned_sat_lower_upper_2: 181; V4T: @ %bb.0: @ %entry 182; V4T-NEXT: ldr r1, .LCPI4_0 183; V4T-NEXT: cmp r0, r1 184; V4T-NEXT: movlt r1, r0 185; V4T-NEXT: bic r0, r1, r1, asr #31 186; V4T-NEXT: bx lr 187; V4T-NEXT: .p2align 2 188; V4T-NEXT: @ %bb.1: 189; V4T-NEXT: .LCPI4_0: 190; V4T-NEXT: .long 8388607 @ 0x7fffff 191; 192; V6-LABEL: unsigned_sat_lower_upper_2: 193; V6: @ %bb.0: @ %entry 194; V6-NEXT: usat r0, #23, r0 195; V6-NEXT: bx lr 196; 197; V6T2-LABEL: unsigned_sat_lower_upper_2: 198; V6T2: @ %bb.0: @ %entry 199; V6T2-NEXT: usat r0, #23, r0 200; V6T2-NEXT: bx lr 201entry: 202 %0 = icmp slt i32 %x, 8388607 203 %saturateUp = select i1 %0, i32 %x, i32 8388607 204 %1 = icmp sgt i32 %saturateUp, 0 205 %saturateLow = select i1 %1, i32 %saturateUp, i32 0 206 ret i32 %saturateLow 207} 208 209; x < k ? (x < 0 ? 0 : x) : k 210define i32 @unsigned_sat_upper_lower_1(i32 %x) #0 { 211; V4T-LABEL: unsigned_sat_upper_lower_1: 212; V4T: @ %bb.0: @ %entry 213; V4T-NEXT: bic r1, r0, r0, asr #31 214; V4T-NEXT: ldr r0, .LCPI5_0 215; V4T-NEXT: cmp r1, r0 216; V4T-NEXT: movlt r0, r1 217; V4T-NEXT: bx lr 218; V4T-NEXT: .p2align 2 219; V4T-NEXT: @ %bb.1: 220; V4T-NEXT: .LCPI5_0: 221; V4T-NEXT: .long 8388607 @ 0x7fffff 222; 223; V6-LABEL: unsigned_sat_upper_lower_1: 224; V6: @ %bb.0: @ %entry 225; V6-NEXT: usat r0, #23, r0 226; V6-NEXT: bx lr 227; 228; V6T2-LABEL: unsigned_sat_upper_lower_1: 229; V6T2: @ %bb.0: @ %entry 230; V6T2-NEXT: usat r0, #23, r0 231; V6T2-NEXT: bx lr 232entry: 233 %0 = icmp sgt i32 %x, 0 234 %saturateLow = select i1 %0, i32 %x, i32 0 235 %1 = icmp slt i32 %saturateLow, 8388607 236 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607 237 ret i32 %saturateUp 238} 239 240; x > k ? k : (x < 0 ? 0 : x) 241define i32 @unsigned_sat_upper_lower_2(i32 %x) #0 { 242; V4T-LABEL: unsigned_sat_upper_lower_2: 243; V4T: @ %bb.0: @ %entry 244; V4T-NEXT: bic r1, r0, r0, asr #31 245; V4T-NEXT: ldr r0, .LCPI6_0 246; V4T-NEXT: cmp r1, r0 247; V4T-NEXT: movlt r0, r1 248; V4T-NEXT: bx lr 249; V4T-NEXT: .p2align 2 250; V4T-NEXT: @ %bb.1: 251; V4T-NEXT: .LCPI6_0: 252; V4T-NEXT: .long 8388607 @ 0x7fffff 253; 254; V6-LABEL: unsigned_sat_upper_lower_2: 255; V6: @ %bb.0: @ %entry 256; V6-NEXT: usat r0, #23, r0 257; V6-NEXT: bx lr 258; 259; V6T2-LABEL: unsigned_sat_upper_lower_2: 260; V6T2: @ %bb.0: @ %entry 261; V6T2-NEXT: usat r0, #23, r0 262; V6T2-NEXT: bx lr 263entry: 264 %0 = icmp sgt i32 %x, 0 265 %saturateLow = select i1 %0, i32 %x, i32 0 266 %1 = icmp slt i32 %saturateLow, 8388607 267 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607 268 ret i32 %saturateUp 269} 270 271; k < x ? k : (x > 0 ? x : 0) 272define i32 @unsigned_sat_upper_lower_3(i32 %x) #0 { 273; V4T-LABEL: unsigned_sat_upper_lower_3: 274; V4T: @ %bb.0: @ %entry 275; V4T-NEXT: bic r1, r0, r0, asr #31 276; V4T-NEXT: ldr r0, .LCPI7_0 277; V4T-NEXT: cmp r1, r0 278; V4T-NEXT: movlt r0, r1 279; V4T-NEXT: bx lr 280; V4T-NEXT: .p2align 2 281; V4T-NEXT: @ %bb.1: 282; V4T-NEXT: .LCPI7_0: 283; V4T-NEXT: .long 8388607 @ 0x7fffff 284; 285; V6-LABEL: unsigned_sat_upper_lower_3: 286; V6: @ %bb.0: @ %entry 287; V6-NEXT: usat r0, #23, r0 288; V6-NEXT: bx lr 289; 290; V6T2-LABEL: unsigned_sat_upper_lower_3: 291; V6T2: @ %bb.0: @ %entry 292; V6T2-NEXT: usat r0, #23, r0 293; V6T2-NEXT: bx lr 294entry: 295 %cmpLow = icmp sgt i32 %x, 0 296 %saturateLow = select i1 %cmpLow, i32 %x, i32 0 297 %0 = icmp slt i32 %saturateLow, 8388607 298 %saturateUp = select i1 %0, i32 %saturateLow, i32 8388607 299 ret i32 %saturateUp 300} 301 302; 303; The following tests check for patterns that should not transform 304; into USAT but are similar enough that could confuse the selector. 305; 306; x > k ? k : (x > 0 ? 0 : x) 307; First condition upper-saturates, second doesn't lower-saturate. 308define i32 @no_unsigned_sat_missing_lower(i32 %x) #0 { 309; V4T-LABEL: no_unsigned_sat_missing_lower: 310; V4T: @ %bb.0: @ %entry 311; V4T-NEXT: ldr r1, .LCPI8_0 312; V4T-NEXT: cmp r0, #8388608 313; V4T-NEXT: andlt r1, r0, r0, asr #31 314; V4T-NEXT: mov r0, r1 315; V4T-NEXT: bx lr 316; V4T-NEXT: .p2align 2 317; V4T-NEXT: @ %bb.1: 318; V4T-NEXT: .LCPI8_0: 319; V4T-NEXT: .long 8388607 @ 0x7fffff 320; 321; V6-LABEL: no_unsigned_sat_missing_lower: 322; V6: @ %bb.0: @ %entry 323; V6-NEXT: ldr r1, .LCPI8_0 324; V6-NEXT: cmp r0, #8388608 325; V6-NEXT: andlt r1, r0, r0, asr #31 326; V6-NEXT: mov r0, r1 327; V6-NEXT: bx lr 328; V6-NEXT: .p2align 2 329; V6-NEXT: @ %bb.1: 330; V6-NEXT: .LCPI8_0: 331; V6-NEXT: .long 8388607 @ 0x7fffff 332; 333; V6T2-LABEL: no_unsigned_sat_missing_lower: 334; V6T2: @ %bb.0: @ %entry 335; V6T2-NEXT: and r1, r0, r0, asr #31 336; V6T2-NEXT: cmp r0, #8388608 337; V6T2-NEXT: movwge r1, #65535 338; V6T2-NEXT: movtge r1, #127 339; V6T2-NEXT: mov r0, r1 340; V6T2-NEXT: bx lr 341entry: 342 %cmpUp = icmp sgt i32 %x, 8388607 343 %0 = icmp slt i32 %x, 0 344 %saturateLow = select i1 %0, i32 %x, i32 0 345 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow 346 ret i32 %saturateUp 347} 348 349; x < k ? k : (x < 0 ? 0 : x) 350; Second condition lower-saturates, first doesn't upper-saturate. 351define i32 @no_unsigned_sat_missing_upper(i32 %x) #0 { 352; V4T-LABEL: no_unsigned_sat_missing_upper: 353; V4T: @ %bb.0: @ %entry 354; V4T-NEXT: ldr r1, .LCPI9_0 355; V4T-NEXT: cmp r0, r1 356; V4T-NEXT: bicge r1, r0, r0, asr #31 357; V4T-NEXT: mov r0, r1 358; V4T-NEXT: bx lr 359; V4T-NEXT: .p2align 2 360; V4T-NEXT: @ %bb.1: 361; V4T-NEXT: .LCPI9_0: 362; V4T-NEXT: .long 8388607 @ 0x7fffff 363; 364; V6-LABEL: no_unsigned_sat_missing_upper: 365; V6: @ %bb.0: @ %entry 366; V6-NEXT: ldr r1, .LCPI9_0 367; V6-NEXT: cmp r0, r1 368; V6-NEXT: bicge r1, r0, r0, asr #31 369; V6-NEXT: mov r0, r1 370; V6-NEXT: bx lr 371; V6-NEXT: .p2align 2 372; V6-NEXT: @ %bb.1: 373; V6-NEXT: .LCPI9_0: 374; V6-NEXT: .long 8388607 @ 0x7fffff 375; 376; V6T2-LABEL: no_unsigned_sat_missing_upper: 377; V6T2: @ %bb.0: @ %entry 378; V6T2-NEXT: movw r2, #65535 379; V6T2-NEXT: bic r1, r0, r0, asr #31 380; V6T2-NEXT: movt r2, #127 381; V6T2-NEXT: cmp r0, r2 382; V6T2-NEXT: movwlt r1, #65535 383; V6T2-NEXT: movtlt r1, #127 384; V6T2-NEXT: mov r0, r1 385; V6T2-NEXT: bx lr 386entry: 387 %cmpUp = icmp slt i32 %x, 8388607 388 %0 = icmp sgt i32 %x, 0 389 %saturateLow = select i1 %0, i32 %x, i32 0 390 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow 391 ret i32 %saturateUp 392} 393 394; Lower constant is different in the select and in the compare 395define i32 @no_unsigned_sat_incorrect_constant(i32 %x) #0 { 396; V4T-LABEL: no_unsigned_sat_incorrect_constant: 397; V4T: @ %bb.0: @ %entry 398; V4T-NEXT: orr r1, r0, r0, asr #31 399; V4T-NEXT: ldr r0, .LCPI10_0 400; V4T-NEXT: cmp r1, r0 401; V4T-NEXT: movlt r0, r1 402; V4T-NEXT: bx lr 403; V4T-NEXT: .p2align 2 404; V4T-NEXT: @ %bb.1: 405; V4T-NEXT: .LCPI10_0: 406; V4T-NEXT: .long 8388607 @ 0x7fffff 407; 408; V6-LABEL: no_unsigned_sat_incorrect_constant: 409; V6: @ %bb.0: @ %entry 410; V6-NEXT: orr r1, r0, r0, asr #31 411; V6-NEXT: ldr r0, .LCPI10_0 412; V6-NEXT: cmp r1, r0 413; V6-NEXT: movlt r0, r1 414; V6-NEXT: bx lr 415; V6-NEXT: .p2align 2 416; V6-NEXT: @ %bb.1: 417; V6-NEXT: .LCPI10_0: 418; V6-NEXT: .long 8388607 @ 0x7fffff 419; 420; V6T2-LABEL: no_unsigned_sat_incorrect_constant: 421; V6T2: @ %bb.0: @ %entry 422; V6T2-NEXT: orr r1, r0, r0, asr #31 423; V6T2-NEXT: movw r0, #65535 424; V6T2-NEXT: movt r0, #127 425; V6T2-NEXT: cmp r1, r0 426; V6T2-NEXT: movlt r0, r1 427; V6T2-NEXT: bx lr 428entry: 429 %cmpLow.inv = icmp sgt i32 %x, -1 430 %saturateLow = select i1 %cmpLow.inv, i32 %x, i32 -1 431 %0 = icmp slt i32 %saturateLow, 8388607 432 %saturateUp = select i1 %0, i32 %saturateLow, i32 8388607 433 ret i32 %saturateUp 434} 435 436; The interval is [0, k] but k+1 is not a power of 2 437define i32 @no_unsigned_sat_incorrect_constant2(i32 %x) #0 { 438; V4T-LABEL: no_unsigned_sat_incorrect_constant2: 439; V4T: @ %bb.0: @ %entry 440; V4T-NEXT: bic r1, r0, r0, asr #31 441; V4T-NEXT: mov r0, #1 442; V4T-NEXT: orr r0, r0, #8388608 443; V4T-NEXT: cmp r1, #8388608 444; V4T-NEXT: movle r0, r1 445; V4T-NEXT: bx lr 446; 447; V6-LABEL: no_unsigned_sat_incorrect_constant2: 448; V6: @ %bb.0: @ %entry 449; V6-NEXT: bic r1, r0, r0, asr #31 450; V6-NEXT: mov r0, #1 451; V6-NEXT: orr r0, r0, #8388608 452; V6-NEXT: cmp r1, #8388608 453; V6-NEXT: movle r0, r1 454; V6-NEXT: bx lr 455; 456; V6T2-LABEL: no_unsigned_sat_incorrect_constant2: 457; V6T2: @ %bb.0: @ %entry 458; V6T2-NEXT: bic r1, r0, r0, asr #31 459; V6T2-NEXT: movw r0, #1 460; V6T2-NEXT: movt r0, #128 461; V6T2-NEXT: cmp r1, #8388608 462; V6T2-NEXT: movle r0, r1 463; V6T2-NEXT: bx lr 464entry: 465 %0 = icmp sgt i32 %x, 0 466 %saturateLow = select i1 %0, i32 %x, i32 0 467 %1 = icmp slt i32 %saturateLow, 8388609 468 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388609 469 ret i32 %saturateUp 470} 471 472; The interval is not [0, k] 473define i32 @no_unsigned_sat_incorrect_interval(i32 %x) #0 { 474; V4T-LABEL: no_unsigned_sat_incorrect_interval: 475; V4T: @ %bb.0: @ %entry 476; V4T-NEXT: ldr r1, .LCPI12_0 477; V4T-NEXT: cmn r0, #4 478; V4T-NEXT: mvnle r0, #3 479; V4T-NEXT: cmp r0, r1 480; V4T-NEXT: movge r0, r1 481; V4T-NEXT: bx lr 482; V4T-NEXT: .p2align 2 483; V4T-NEXT: @ %bb.1: 484; V4T-NEXT: .LCPI12_0: 485; V4T-NEXT: .long 8388607 @ 0x7fffff 486; 487; V6-LABEL: no_unsigned_sat_incorrect_interval: 488; V6: @ %bb.0: @ %entry 489; V6-NEXT: ldr r1, .LCPI12_0 490; V6-NEXT: cmn r0, #4 491; V6-NEXT: mvnle r0, #3 492; V6-NEXT: cmp r0, r1 493; V6-NEXT: movge r0, r1 494; V6-NEXT: bx lr 495; V6-NEXT: .p2align 2 496; V6-NEXT: @ %bb.1: 497; V6-NEXT: .LCPI12_0: 498; V6-NEXT: .long 8388607 @ 0x7fffff 499; 500; V6T2-LABEL: no_unsigned_sat_incorrect_interval: 501; V6T2: @ %bb.0: @ %entry 502; V6T2-NEXT: cmn r0, #4 503; V6T2-NEXT: movw r1, #65535 504; V6T2-NEXT: mvnle r0, #3 505; V6T2-NEXT: movt r1, #127 506; V6T2-NEXT: cmp r0, r1 507; V6T2-NEXT: movge r0, r1 508; V6T2-NEXT: bx lr 509entry: 510 %0 = icmp sgt i32 %x, -4 511 %saturateLow = select i1 %0, i32 %x, i32 -4 512 %1 = icmp slt i32 %saturateLow, 8388607 513 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607 514 ret i32 %saturateUp 515} 516 517; The returned value (y) is not the same as the tested value (x). 518define i32 @no_unsigned_sat_incorrect_return(i32 %x, i32 %y) #0 { 519; V4T-LABEL: no_unsigned_sat_incorrect_return: 520; V4T: @ %bb.0: @ %entry 521; V4T-NEXT: cmp r0, #0 522; V4T-NEXT: ldr r2, .LCPI13_0 523; V4T-NEXT: movmi r1, #0 524; V4T-NEXT: cmp r0, #8388608 525; V4T-NEXT: movlt r2, r1 526; V4T-NEXT: mov r0, r2 527; V4T-NEXT: bx lr 528; V4T-NEXT: .p2align 2 529; V4T-NEXT: @ %bb.1: 530; V4T-NEXT: .LCPI13_0: 531; V4T-NEXT: .long 8388607 @ 0x7fffff 532; 533; V6-LABEL: no_unsigned_sat_incorrect_return: 534; V6: @ %bb.0: @ %entry 535; V6-NEXT: cmp r0, #0 536; V6-NEXT: ldr r2, .LCPI13_0 537; V6-NEXT: movmi r1, #0 538; V6-NEXT: cmp r0, #8388608 539; V6-NEXT: movlt r2, r1 540; V6-NEXT: mov r0, r2 541; V6-NEXT: bx lr 542; V6-NEXT: .p2align 2 543; V6-NEXT: @ %bb.1: 544; V6-NEXT: .LCPI13_0: 545; V6-NEXT: .long 8388607 @ 0x7fffff 546; 547; V6T2-LABEL: no_unsigned_sat_incorrect_return: 548; V6T2: @ %bb.0: @ %entry 549; V6T2-NEXT: cmp r0, #0 550; V6T2-NEXT: movwmi r1, #0 551; V6T2-NEXT: cmp r0, #8388608 552; V6T2-NEXT: movwge r1, #65535 553; V6T2-NEXT: movtge r1, #127 554; V6T2-NEXT: mov r0, r1 555; V6T2-NEXT: bx lr 556entry: 557 %cmpUp = icmp sgt i32 %x, 8388607 558 %cmpLow = icmp slt i32 %x, 0 559 %saturateLow = select i1 %cmpLow, i32 0, i32 %y 560 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow 561 ret i32 %saturateUp 562} 563 564; One of the values in a compare (y) is not the same as the rest 565; of the compare and select values (x). 566define i32 @no_unsigned_sat_incorrect_compare(i32 %x, i32 %y) #0 { 567; V4T-LABEL: no_unsigned_sat_incorrect_compare: 568; V4T: @ %bb.0: @ %entry 569; V4T-NEXT: ldr r2, .LCPI14_0 570; V4T-NEXT: cmp r1, #0 571; V4T-NEXT: mov r1, r0 572; V4T-NEXT: movmi r1, #0 573; V4T-NEXT: cmp r0, #8388608 574; V4T-NEXT: movge r1, r2 575; V4T-NEXT: mov r0, r1 576; V4T-NEXT: bx lr 577; V4T-NEXT: .p2align 2 578; V4T-NEXT: @ %bb.1: 579; V4T-NEXT: .LCPI14_0: 580; V4T-NEXT: .long 8388607 @ 0x7fffff 581; 582; V6-LABEL: no_unsigned_sat_incorrect_compare: 583; V6: @ %bb.0: @ %entry 584; V6-NEXT: ldr r2, .LCPI14_0 585; V6-NEXT: cmp r1, #0 586; V6-NEXT: mov r1, r0 587; V6-NEXT: movmi r1, #0 588; V6-NEXT: cmp r0, #8388608 589; V6-NEXT: movge r1, r2 590; V6-NEXT: mov r0, r1 591; V6-NEXT: bx lr 592; V6-NEXT: .p2align 2 593; V6-NEXT: @ %bb.1: 594; V6-NEXT: .LCPI14_0: 595; V6-NEXT: .long 8388607 @ 0x7fffff 596; 597; V6T2-LABEL: no_unsigned_sat_incorrect_compare: 598; V6T2: @ %bb.0: @ %entry 599; V6T2-NEXT: cmp r1, #0 600; V6T2-NEXT: mov r1, r0 601; V6T2-NEXT: movwmi r1, #0 602; V6T2-NEXT: cmp r0, #8388608 603; V6T2-NEXT: movwge r1, #65535 604; V6T2-NEXT: movtge r1, #127 605; V6T2-NEXT: mov r0, r1 606; V6T2-NEXT: bx lr 607entry: 608 %cmpUp = icmp sgt i32 %x, 8388607 609 %cmpLow = icmp slt i32 %y, 0 610 %saturateLow = select i1 %cmpLow, i32 0, i32 %x 611 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow 612 ret i32 %saturateUp 613} 614