1; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV 2; RUN: llc -march=mips -mcpu=mips32 -regalloc=basic < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV 3; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV 4; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMP 5; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV 6; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV 7; RUN: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMP 8 9@i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4 10@i3 = common global i32* null, align 4 11 12; ALL-LABEL: cmov1: 13 14; 32-CMOV-DAG: lw $[[R0:[0-9]+]], %got(i3) 15; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(i1) 16; 32-CMOV-DAG: movn $[[R0]], $[[R1]], $4 17; 32-CMOV-DAG: lw $2, 0($[[R0]]) 18 19; 32-CMP-DAG: lw $[[R0:[0-9]+]], %got(i3) 20; 32-CMP-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(i1) 21; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R1]], $4 22; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R0]], $4 23; 32-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]] 24; 32-CMP-DAG: lw $2, 0($[[T2]]) 25 26; 64-CMOV-DAG: ldr $[[R0:[0-9]+]] 27; 64-CMOV-DAG: ld $[[R1:[0-9]+]], %got_disp(i1) 28; 64-CMOV-DAG: movn $[[R0]], $[[R1]], $4 29 30; 64-CMP-DAG: ld $[[R0:[0-9]+]], %got_disp(i3)( 31; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(i1) 32; FIXME: This sll works around an implementation detail in the code generator 33; (setcc's result is i32 so bits 32-63 are undefined). It's not really 34; needed. 35; 64-CMP-DAG: sll $[[CC:[0-9]+]], $4, 0 36; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R1]], $[[CC]] 37; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R0]], $[[CC]] 38; 64-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]] 39; 64-CMP-DAG: ld $2, 0($[[T2]]) 40 41define i32* @cmov1(i32 signext %s) nounwind readonly { 42entry: 43 %tobool = icmp ne i32 %s, 0 44 %tmp1 = load i32*, i32** @i3, align 4 45 %cond = select i1 %tobool, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @i1, i32 0, i32 0), i32* %tmp1 46 ret i32* %cond 47} 48 49@c = global i32 1, align 4 50@d = global i32 0, align 4 51 52; ALL-LABEL: cmov2: 53 54; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(d) 55; 32-CMOV-DAG: addiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got(c) 56; 32-CMOV-DAG: movn $[[R1]], $[[R0]], $4 57; 32-CMOV-DAG: lw $2, 0($[[R0]]) 58 59; 32-CMP-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(d) 60; 32-CMP-DAG: addiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got(c) 61; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R0]], $4 62; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R1]], $4 63; 32-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]] 64; 32-CMP-DAG: lw $2, 0($[[T2]]) 65 66; 64-CMOV: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) 67; 64-CMOV: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) 68; 64-CMOV: movn $[[R1]], $[[R0]], $4 69 70; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) 71; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) 72; FIXME: This sll works around an implementation detail in the code generator 73; (setcc's result is i32 so bits 32-63 are undefined). It's not really 74; needed. 75; 64-CMP-DAG: sll $[[CC:[0-9]+]], $4, 0 76; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R0]], $[[CC]] 77; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R1]], $[[CC]] 78; 64-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]] 79; 64-CMP-DAG: lw $2, 0($[[T2]]) 80 81define i32 @cmov2(i32 signext %s) nounwind readonly { 82entry: 83 %tobool = icmp ne i32 %s, 0 84 %tmp1 = load i32, i32* @c, align 4 85 %tmp2 = load i32, i32* @d, align 4 86 %cond = select i1 %tobool, i32 %tmp1, i32 %tmp2 87 ret i32 %cond 88} 89 90; ALL-LABEL: cmov3: 91 92; We won't check the result register since we can't know if the move is first 93; or last. We do know it will be either one of two registers so we can at least 94; check that. 95 96; 32-CMOV: xori $[[R0:[0-9]+]], $4, 234 97; 32-CMOV: movz ${{[26]}}, $5, $[[R0]] 98 99; 32-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234 100; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $5, $[[CC]] 101; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $6, $[[CC]] 102; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 103 104; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234 105; 64-CMOV: movz ${{[26]}}, $5, $[[R0]] 106 107; 64-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234 108; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $5, $[[CC]] 109; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $6, $[[CC]] 110; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 111 112define i32 @cmov3(i32 signext %a, i32 signext %b, i32 signext %c) nounwind readnone { 113entry: 114 %cmp = icmp eq i32 %a, 234 115 %cond = select i1 %cmp, i32 %b, i32 %c 116 ret i32 %cond 117} 118 119; ALL-LABEL: cmov3_ne: 120 121; We won't check the result register since we can't know if the move is first 122; or last. We do know it will be either one of two registers so we can at least 123; check that. 124 125; FIXME: Use xori instead of addiu+xor. 126; 32-CMOV: addiu $[[R0:[0-9]+]], $zero, 234 127; 32-CMOV: xor $[[R1:[0-9]+]], $4, $[[R0]] 128; 32-CMOV: movn ${{[26]}}, $5, $[[R1]] 129 130; 32-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234 131; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $5, $[[CC]] 132; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $6, $[[CC]] 133; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 134 135; FIXME: Use xori instead of addiu+xor. 136; 64-CMOV: addiu $[[R0:[0-9]+]], $zero, 234 137; 64-CMOV: xor $[[R1:[0-9]+]], $4, $[[R0]] 138; 64-CMOV: movn ${{[26]}}, $5, $[[R1]] 139 140; 64-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234 141; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $5, $[[CC]] 142; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $6, $[[CC]] 143; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 144 145define i32 @cmov3_ne(i32 signext %a, i32 signext %b, i32 signext %c) nounwind readnone { 146entry: 147 %cmp = icmp ne i32 %a, 234 148 %cond = select i1 %cmp, i32 %b, i32 %c 149 ret i32 %cond 150} 151 152; ALL-LABEL: cmov4: 153 154; We won't check the result register since we can't know if the move is first 155; or last. We do know it will be one of two registers so we can at least check 156; that. 157 158; 32-CMOV-DAG: xori $[[R0:[0-9]+]], $4, 234 159; 32-CMOV-DAG: lw $[[R1:2]], 16($sp) 160; 32-CMOV-DAG: lw $[[R2:3]], 20($sp) 161; 32-CMOV-DAG: movz $[[R1]], $6, $[[R0]] 162; 32-CMOV-DAG: movz $[[R2]], $7, $[[R0]] 163 164; 32-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234 165; 32-CMP-DAG: lw $[[R1:[0-9]+]], 16($sp) 166; 32-CMP-DAG: lw $[[R2:[0-9]+]], 20($sp) 167; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $6, $[[R0]] 168; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $7, $[[R0]] 169; 32-CMP-DAG: selnez $[[T2:[0-9]+]], $[[R1]], $[[R0]] 170; 32-CMP-DAG: selnez $[[T3:[0-9]+]], $[[R2]], $[[R0]] 171; 32-CMP-DAG: or $2, $[[T0]], $[[T2]] 172; 32-CMP-DAG: or $3, $[[T1]], $[[T3]] 173 174; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234 175; 64-CMOV: movz ${{[26]}}, $5, $[[R0]] 176 177; 64-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234 178; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $5, $[[R0]] 179; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $6, $[[R0]] 180; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 181 182define i64 @cmov4(i32 signext %a, i64 %b, i64 %c) nounwind readnone { 183entry: 184 %cmp = icmp eq i32 %a, 234 185 %cond = select i1 %cmp, i64 %b, i64 %c 186 ret i64 %cond 187} 188 189; ALL-LABEL: cmov4_ne: 190 191; We won't check the result register since we can't know if the move is first 192; or last. We do know it will be one of two registers so we can at least check 193; that. 194 195; FIXME: Use xori instead of addiu+xor. 196; 32-CMOV-DAG: addiu $[[R0:[0-9]+]], $zero, 234 197; 32-CMOV-DAG: xor $[[R1:[0-9]+]], $4, $[[R0]] 198; 32-CMOV-DAG: lw $[[R2:2]], 16($sp) 199; 32-CMOV-DAG: lw $[[R3:3]], 20($sp) 200; 32-CMOV-DAG: movn $[[R2]], $6, $[[R1]] 201; 32-CMOV-DAG: movn $[[R3]], $7, $[[R1]] 202 203; 32-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234 204; 32-CMP-DAG: lw $[[R1:[0-9]+]], 16($sp) 205; 32-CMP-DAG: lw $[[R2:[0-9]+]], 20($sp) 206; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $6, $[[R0]] 207; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $7, $[[R0]] 208; 32-CMP-DAG: seleqz $[[T2:[0-9]+]], $[[R1]], $[[R0]] 209; 32-CMP-DAG: seleqz $[[T3:[0-9]+]], $[[R2]], $[[R0]] 210; 32-CMP-DAG: or $2, $[[T0]], $[[T2]] 211; 32-CMP-DAG: or $3, $[[T1]], $[[T3]] 212 213; FIXME: Use xori instead of addiu+xor. 214; 64-CMOV: addiu $[[R0:[0-9]+]], $zero, 234 215; 64-CMOV: xor $[[R1:[0-9]+]], $4, $[[R0]] 216; 64-CMOV: movn ${{[26]}}, $5, $[[R1]] 217 218; 64-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234 219; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $5, $[[R0]] 220; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $6, $[[R0]] 221; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 222 223define i64 @cmov4_ne(i32 signext %a, i64 %b, i64 %c) nounwind readnone { 224entry: 225 %cmp = icmp ne i32 %a, 234 226 %cond = select i1 %cmp, i64 %b, i64 %c 227 ret i64 %cond 228} 229 230; slti and conditional move. 231; 232; Check that, pattern 233; (select (setgt a, N), t, f) 234; turns into 235; (movz t, (setlt a, N + 1), f) 236; if N + 1 fits in 16-bit. 237 238; ALL-LABEL: slti0: 239 240; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 241; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 242; 32-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 243; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 244 245; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 246; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 247; 32-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 248; FIXME: We can do better than this by using selccz to choose between +0 and +2 249; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 250; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 251; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 252 253; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 254; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 255; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 256; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 257 258; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 259; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 260; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 261; FIXME: We can do better than this by using selccz to choose between +0 and +2 262; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 263; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 264; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 265 266define i32 @slti0(i32 signext %a) { 267entry: 268 %cmp = icmp sgt i32 %a, 32766 269 %cond = select i1 %cmp, i32 3, i32 5 270 ret i32 %cond 271} 272 273; ALL-LABEL: slti1: 274 275; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 276; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 277; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 278; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 279; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] 280 281; 32-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 282; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 283; 32-CMP-DAG: addiu $[[I32767:[0-9]+]], $zero, 32767 284; 32-CMP-DAG: slt $[[R0:[0-9]+]], $[[I32767]], $4 285; FIXME: We can do better than this by using selccz to choose between -0 and -2 286; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] 287; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 288; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 289 290; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 291; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 292; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 293; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 294; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] 295 296; 64-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 297; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 298; 64-CMP-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 299; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 300; FIXME: We can do better than this by using selccz to choose between -0 and -2 301; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] 302; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 303; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 304 305define i32 @slti1(i32 signext %a) { 306entry: 307 %cmp = icmp sgt i32 %a, 32767 308 %cond = select i1 %cmp, i32 7, i32 5 309 ret i32 %cond 310} 311 312; ALL-LABEL: slti2: 313 314; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 315; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 316; 32-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 317; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 318 319; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 320; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 321; 32-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 322; FIXME: We can do better than this by using selccz to choose between +0 and +2 323; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 324; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 325; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 326 327; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 328; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 329; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 330; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 331 332; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 333; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 334; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 335; FIXME: We can do better than this by using selccz to choose between +0 and +2 336; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 337; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 338; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 339 340define i32 @slti2(i32 signext %a) { 341entry: 342 %cmp = icmp sgt i32 %a, -32769 343 %cond = select i1 %cmp, i32 3, i32 5 344 ret i32 %cond 345} 346 347; ALL-LABEL: slti3: 348 349; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 350; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 351; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 352; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 353; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 354; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] 355 356; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 357; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 358; 32-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 359; 32-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 360; 32-CMP-DAG: slt $[[R0:[0-9]+]], $[[I32767]], $4 361; FIXME: We can do better than this by using selccz to choose between -0 and -2 362; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] 363; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 364; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 365 366; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 367; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 368; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 369; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 370; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 371; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] 372 373; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 374; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 375; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 376; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 377; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[IMM]], $4 378; FIXME: We can do better than this by using selccz to choose between -0 and -2 379; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] 380; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 381; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 382 383define i32 @slti3(i32 signext %a) { 384entry: 385 %cmp = icmp sgt i32 %a, -32770 386 %cond = select i1 %cmp, i32 3, i32 5 387 ret i32 %cond 388} 389 390; 64-bit patterns. 391 392; ALL-LABEL: slti64_0: 393 394; 32-CMOV-DAG: slt $[[CC:[0-9]+]], $zero, $4 395; 32-CMOV-DAG: addiu $[[I32766:[0-9]+]], $zero, 32766 396; 32-CMOV-DAG: sltu $[[R1:[0-9]+]], $[[I32766]], $5 397; 32-CMOV-DAG: movz $[[CC:[0-9]+]], $[[R1]], $4 398; 32-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 399; 32-CMOV-DAG: addiu $[[I4:3]], $zero, 4 400; 32-CMOV-DAG: movn $[[I4]], $[[I5]], $[[CC]] 401; 32-CMOV-DAG: addiu $2, $zero, 0 402 403; 32-CMP-DAG: slt $[[CC0:[0-9]+]], $zero, $4 404; 32-CMP-DAG: addiu $[[I32766:[0-9]+]], $zero, 32766 405; 32-CMP-DAG: sltu $[[CC1:[0-9]+]], $[[I32766]], $5 406; 32-CMP-DAG: selnez $[[CC2:[0-9]+]], $[[CC0]], $4 407; 32-CMP-DAG: seleqz $[[CC3:[0-9]+]], $[[CC1]], $4 408; 32-CMP: or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]] 409; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 410; 32-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 411; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]] 412; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]] 413; 32-CMP-DAG: or $3, $[[T1]], $[[T0]] 414; 32-CMP-DAG: addiu $2, $zero, 0 415 416; 64-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 417; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4 418; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 419; 64-CMOV-DAG: movz $[[I4]], $[[I5]], $[[R0]] 420 421; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 422; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 423; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 424; FIXME: We can do better than this by adding/subtracting the result of slti 425; to/from one of the constants. 426; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R0]] 427; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]] 428; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 429 430define i64 @slti64_0(i64 %a) { 431entry: 432 %cmp = icmp sgt i64 %a, 32766 433 %conv = select i1 %cmp, i64 5, i64 4 434 ret i64 %conv 435} 436 437; ALL-LABEL: slti64_1: 438 439; 32-CMOV-DAG: slt $[[CC:[0-9]+]], $zero, $4 440; 32-CMOV-DAG: addiu $[[I32766:[0-9]+]], $zero, 32767 441; 32-CMOV-DAG: sltu $[[R1:[0-9]+]], $[[I32766]], $5 442; 32-CMOV-DAG: movz $[[CC:[0-9]+]], $[[R1]], $4 443; 32-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 444; 32-CMOV-DAG: addiu $[[I4:3]], $zero, 4 445; 32-CMOV-DAG: movn $[[I4]], $[[I5]], $[[CC]] 446; 32-CMOV-DAG: addiu $2, $zero, 0 447 448; 32-CMP-DAG: slt $[[CC0:[0-9]+]], $zero, $4 449; 32-CMP-DAG: addiu $[[I32766:[0-9]+]], $zero, 32767 450; 32-CMP-DAG: sltu $[[CC1:[0-9]+]], $[[I32766]], $5 451; 32-CMP-DAG: selnez $[[CC2:[0-9]+]], $[[CC0]], $4 452; 32-CMP-DAG: seleqz $[[CC3:[0-9]+]], $[[CC1]], $4 453; 32-CMP: or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]] 454; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 455; 32-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 456; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]] 457; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]] 458; 32-CMP-DAG: or $3, $[[T1]], $[[T0]] 459; 32-CMP-DAG: addiu $2, $zero, 0 460 461; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 462; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4 463; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767 464; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 465; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]] 466 467; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 468; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4 469; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767 470; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 471; FIXME: We can do better than this by using selccz to choose between -0 and -2 472; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] 473; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] 474; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 475 476define i64 @slti64_1(i64 %a) { 477entry: 478 %cmp = icmp sgt i64 %a, 32767 479 %conv = select i1 %cmp, i64 5, i64 4 480 ret i64 %conv 481} 482 483; ALL-LABEL: slti64_2: 484 485; FIXME: The 32-bit versions of this test are too complicated to reasonably 486; match at the moment. They do show some missing optimizations though 487; such as: 488; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c) 489 490; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 491; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4 492; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 493; 64-CMOV-DAG: movz $[[I4]], $[[I3]], $[[R0]] 494 495; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 496; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 497; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 498; FIXME: We can do better than this by adding/subtracting the result of slti 499; to/from one of the constants. 500; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 501; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]] 502; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 503 504define i64 @slti64_2(i64 %a) { 505entry: 506 %cmp = icmp sgt i64 %a, -32769 507 %conv = select i1 %cmp, i64 3, i64 4 508 ret i64 %conv 509} 510 511; ALL-LABEL: slti64_3: 512 513; FIXME: The 32-bit versions of this test are too complicated to reasonably 514; match at the moment. They do show some missing optimizations though 515; such as: 516; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c) 517 518; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 519; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4 520; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766 521; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 522; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]] 523 524; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 525; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4 526; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766 527; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 528; FIXME: We can do better than this by using selccz to choose between -0 and -2 529; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] 530; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] 531; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 532 533define i64 @slti64_3(i64 %a) { 534entry: 535 %cmp = icmp sgt i64 %a, -32770 536 %conv = select i1 %cmp, i64 5, i64 4 537 ret i64 %conv 538} 539 540; sltiu instructions. 541 542; ALL-LABEL: sltiu0: 543 544; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 545; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 546; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 547; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 548 549; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 550; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 551; 32-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 552; FIXME: We can do better than this by using selccz to choose between +0 and +2 553; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 554; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 555; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 556 557; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 558; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 559; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 560; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 561 562; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 563; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 564; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 565; FIXME: We can do better than this by using selccz to choose between +0 and +2 566; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 567; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 568; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 569 570define i32 @sltiu0(i32 signext %a) { 571entry: 572 %cmp = icmp ugt i32 %a, 32766 573 %cond = select i1 %cmp, i32 3, i32 5 574 ret i32 %cond 575} 576 577; ALL-LABEL: sltiu1: 578 579; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 580; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 581; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 582; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 583; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] 584 585; 32-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 586; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 587; 32-CMP-DAG: addiu $[[I32767:[0-9]+]], $zero, 32767 588; 32-CMP-DAG: sltu $[[R0:[0-9]+]], $[[I32767]], $4 589; FIXME: We can do better than this by using selccz to choose between -0 and -2 590; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] 591; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 592; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 593 594; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 595; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 596; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 597; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 598; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] 599 600; 64-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 601; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 602; 64-CMP-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 603; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 604; FIXME: We can do better than this by using selccz to choose between -0 and -2 605; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] 606; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 607; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 608 609define i32 @sltiu1(i32 signext %a) { 610entry: 611 %cmp = icmp ugt i32 %a, 32767 612 %cond = select i1 %cmp, i32 7, i32 5 613 ret i32 %cond 614} 615 616; ALL-LABEL: sltiu2: 617 618; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 619; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 620; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 621; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 622 623; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 624; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 625; 32-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 626; FIXME: We can do better than this by using selccz to choose between +0 and +2 627; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 628; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 629; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 630 631; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 632; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 633; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 634; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 635 636; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 637; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 638; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 639; FIXME: We can do better than this by using selccz to choose between +0 and +2 640; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 641; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 642; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 643 644define i32 @sltiu2(i32 signext %a) { 645entry: 646 %cmp = icmp ugt i32 %a, -32769 647 %cond = select i1 %cmp, i32 3, i32 5 648 ret i32 %cond 649} 650 651; ALL-LABEL: sltiu3: 652 653; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 654; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 655; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 656; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 657; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 658; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] 659 660; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 661; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 662; 32-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 663; 32-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 664; 32-CMP-DAG: sltu $[[R0:[0-9]+]], $[[I32767]], $4 665; FIXME: We can do better than this by using selccz to choose between -0 and -2 666; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] 667; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 668; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 669 670; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 671; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 672; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 673; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 674; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 675; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] 676 677; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 678; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 679; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 680; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 681; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[IMM]], $4 682; FIXME: We can do better than this by using selccz to choose between -0 and -2 683; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] 684; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 685; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 686 687define i32 @sltiu3(i32 signext %a) { 688entry: 689 %cmp = icmp ugt i32 %a, -32770 690 %cond = select i1 %cmp, i32 3, i32 5 691 ret i32 %cond 692} 693 694; Check if 695; (select (setxx a, N), x, x-1) or 696; (select (setxx a, N), x-1, x) 697; doesn't generate conditional moves 698; for constant operands whose difference is |1| 699 700define i32 @slti4(i32 signext %a) nounwind readnone { 701 %1 = icmp slt i32 %a, 7 702 %2 = select i1 %1, i32 4, i32 3 703 ret i32 %2 704} 705 706; ALL-LABEL: slti4: 707 708; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 709; 32-CMOV-DAG: addiu $2, [[R1]], 3 710; 32-CMOV-NOT: movn 711 712; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 713; 32-CMP-DAG: addiu $2, [[R1]], 3 714; 32-CMP-NOT: seleqz 715; 32-CMP-NOT: selnez 716 717; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 718; 64-CMOV-DAG: addiu $2, [[R1]], 3 719; 64-CMOV-NOT: movn 720 721; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 722; 64-CMP-DAG: addiu $2, [[R1]], 3 723; 64-CMP-NOT: seleqz 724; 64-CMP-NOT: selnez 725 726define i32 @slti5(i32 signext %a) nounwind readnone { 727 %1 = icmp slt i32 %a, 7 728 %2 = select i1 %1, i32 -3, i32 -4 729 ret i32 %2 730} 731 732; ALL-LABEL: slti5: 733 734; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 735; 32-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 736; 32-CMOV-NOT: movn 737 738; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 739; 32-CMP-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 740; 32-CMP-NOT: seleqz 741; 32-CMP-NOT: selnez 742 743; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 744; 64-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 745; 64-CMOV-NOT: movn 746 747; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 748; 64-CMP-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 749; 64-CMP-NOT: seleqz 750; 64-CMP-NOT: selnez 751 752define i32 @slti6(i32 signext %a) nounwind readnone { 753 %1 = icmp slt i32 %a, 7 754 %2 = select i1 %1, i32 3, i32 4 755 ret i32 %2 756} 757 758; ALL-LABEL: slti6: 759 760; ALL-DAG: addiu [[R1:\$[0-9]+]], $zero, 6 761; ALL-DAG: slt [[R1]], [[R1]], $4 762; ALL-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 763; ALL-NOT: movn 764; ALL-NOT: seleqz 765; ALL-NOT: selnez 766