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 %s) nounwind readonly { 42entry: 43 %tobool = icmp ne i32 %s, 0 44 %tmp1 = load i32** @i3, align 4 45 %cond = select i1 %tobool, i32* getelementptr inbounds ([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 %s) nounwind readonly { 82entry: 83 %tobool = icmp ne i32 %s, 0 84 %tmp1 = load i32* @c, align 4 85 %tmp2 = load 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 %a, i32 %b, i32 %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: cmov4: 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 one of two registers so we can at least check 123; that. 124 125; 32-CMOV-DAG: xori $[[R0:[0-9]+]], $4, 234 126; 32-CMOV-DAG: lw $[[R1:2]], 16($sp) 127; 32-CMOV-DAG: lw $[[R2:3]], 20($sp) 128; 32-CMOV-DAG: movz $[[R1]], $6, $[[R0]] 129; 32-CMOV-DAG: movz $[[R2]], $7, $[[R0]] 130 131; 32-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234 132; 32-CMP-DAG: lw $[[R1:[0-9]+]], 16($sp) 133; 32-CMP-DAG: lw $[[R2:[0-9]+]], 20($sp) 134; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $6, $[[R0]] 135; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $7, $[[R0]] 136; 32-CMP-DAG: selnez $[[T2:[0-9]+]], $[[R1]], $[[R0]] 137; 32-CMP-DAG: selnez $[[T3:[0-9]+]], $[[R2]], $[[R0]] 138; 32-CMP-DAG: or $2, $[[T0]], $[[T2]] 139; 32-CMP-DAG: or $3, $[[T1]], $[[T3]] 140 141; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234 142; 64-CMOV: movz ${{[26]}}, $5, $[[R0]] 143 144; 64-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234 145; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $5, $[[R0]] 146; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $6, $[[R0]] 147; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 148 149define i64 @cmov4(i32 %a, i64 %b, i64 %c) nounwind readnone { 150entry: 151 %cmp = icmp eq i32 %a, 234 152 %cond = select i1 %cmp, i64 %b, i64 %c 153 ret i64 %cond 154} 155 156; slti and conditional move. 157; 158; Check that, pattern 159; (select (setgt a, N), t, f) 160; turns into 161; (movz t, (setlt a, N + 1), f) 162; if N + 1 fits in 16-bit. 163 164; ALL-LABEL: slti0: 165 166; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 167; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 168; 32-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 169; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 170 171; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 172; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 173; 32-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 174; FIXME: We can do better than this by using selccz to choose between +0 and +2 175; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 176; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 177; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 178 179; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 180; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 181; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 182; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 183 184; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 185; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 186; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 187; FIXME: We can do better than this by using selccz to choose between +0 and +2 188; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 189; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 190; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 191 192define i32 @slti0(i32 %a) { 193entry: 194 %cmp = icmp sgt i32 %a, 32766 195 %cond = select i1 %cmp, i32 3, i32 5 196 ret i32 %cond 197} 198 199; ALL-LABEL: slti1: 200 201; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 202; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 203; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 204; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 205; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] 206 207; 32-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 208; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 209; 32-CMP-DAG: addiu $[[I32767:[0-9]+]], $zero, 32767 210; 32-CMP-DAG: slt $[[R0:[0-9]+]], $[[I32767]], $4 211; FIXME: We can do better than this by using selccz to choose between -0 and -2 212; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] 213; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 214; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 215 216; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 217; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 218; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 219; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 220; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] 221 222; 64-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 223; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 224; 64-CMP-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 225; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 226; FIXME: We can do better than this by using selccz to choose between -0 and -2 227; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] 228; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 229; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 230 231define i32 @slti1(i32 %a) { 232entry: 233 %cmp = icmp sgt i32 %a, 32767 234 %cond = select i1 %cmp, i32 7, i32 5 235 ret i32 %cond 236} 237 238; ALL-LABEL: slti2: 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, -32768 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, -32768 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, -32768 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, -32768 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 @slti2(i32 %a) { 267entry: 268 %cmp = icmp sgt i32 %a, -32769 269 %cond = select i1 %cmp, i32 3, i32 5 270 ret i32 %cond 271} 272 273; ALL-LABEL: slti3: 274 275; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 276; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 277; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 278; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 279; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 280; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] 281 282; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 283; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 284; 32-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 285; 32-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 286; 32-CMP-DAG: slt $[[R0:[0-9]+]], $[[I32767]], $4 287; FIXME: We can do better than this by using selccz to choose between -0 and -2 288; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] 289; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 290; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 291 292; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 293; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 294; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 295; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 296; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 297; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] 298 299; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 300; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 301; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 302; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 303; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[IMM]], $4 304; FIXME: We can do better than this by using selccz to choose between -0 and -2 305; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] 306; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 307; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 308 309define i32 @slti3(i32 %a) { 310entry: 311 %cmp = icmp sgt i32 %a, -32770 312 %cond = select i1 %cmp, i32 3, i32 5 313 ret i32 %cond 314} 315 316; 64-bit patterns. 317 318; ALL-LABEL: slti64_0: 319 320; 32-CMOV-DAG: slt $[[CC:[0-9]+]], $zero, $4 321; 32-CMOV-DAG: addiu $[[I32766:[0-9]+]], $zero, 32766 322; 32-CMOV-DAG: sltu $[[R1:[0-9]+]], $[[I32766]], $5 323; 32-CMOV-DAG: movz $[[CC:[0-9]+]], $[[R1]], $4 324; 32-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 325; 32-CMOV-DAG: addiu $[[I4:3]], $zero, 4 326; 32-CMOV-DAG: movn $[[I4]], $[[I5]], $[[CC]] 327; 32-CMOV-DAG: addiu $2, $zero, 0 328 329; 32-CMP-DAG: slt $[[CC0:[0-9]+]], $zero, $4 330; 32-CMP-DAG: addiu $[[I32766:[0-9]+]], $zero, 32766 331; 32-CMP-DAG: sltu $[[CC1:[0-9]+]], $[[I32766]], $5 332; 32-CMP-DAG: selnez $[[CC2:[0-9]+]], $[[CC0]], $4 333; 32-CMP-DAG: seleqz $[[CC3:[0-9]+]], $[[CC1]], $4 334; 32-CMP: or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]] 335; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 336; 32-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 337; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]] 338; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]] 339; 32-CMP-DAG: or $3, $[[T1]], $[[T0]] 340; 32-CMP-DAG: addiu $2, $zero, 0 341 342; 64-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 343; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4 344; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 345; 64-CMOV-DAG: movz $[[I4]], $[[I5]], $[[R0]] 346 347; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 348; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 349; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 350; FIXME: We can do better than this by adding/subtracting the result of slti 351; to/from one of the constants. 352; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R0]] 353; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]] 354; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 355 356define i64 @slti64_0(i64 %a) { 357entry: 358 %cmp = icmp sgt i64 %a, 32766 359 %conv = select i1 %cmp, i64 5, i64 4 360 ret i64 %conv 361} 362 363; ALL-LABEL: slti64_1: 364 365; 32-CMOV-DAG: slt $[[CC:[0-9]+]], $zero, $4 366; 32-CMOV-DAG: addiu $[[I32766:[0-9]+]], $zero, 32767 367; 32-CMOV-DAG: sltu $[[R1:[0-9]+]], $[[I32766]], $5 368; 32-CMOV-DAG: movz $[[CC:[0-9]+]], $[[R1]], $4 369; 32-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 370; 32-CMOV-DAG: addiu $[[I4:3]], $zero, 4 371; 32-CMOV-DAG: movn $[[I4]], $[[I5]], $[[CC]] 372; 32-CMOV-DAG: addiu $2, $zero, 0 373 374; 32-CMP-DAG: slt $[[CC0:[0-9]+]], $zero, $4 375; 32-CMP-DAG: addiu $[[I32766:[0-9]+]], $zero, 32767 376; 32-CMP-DAG: sltu $[[CC1:[0-9]+]], $[[I32766]], $5 377; 32-CMP-DAG: selnez $[[CC2:[0-9]+]], $[[CC0]], $4 378; 32-CMP-DAG: seleqz $[[CC3:[0-9]+]], $[[CC1]], $4 379; 32-CMP: or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]] 380; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 381; 32-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 382; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]] 383; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]] 384; 32-CMP-DAG: or $3, $[[T1]], $[[T0]] 385; 32-CMP-DAG: addiu $2, $zero, 0 386 387; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 388; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4 389; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767 390; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 391; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]] 392 393; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 394; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4 395; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767 396; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 397; FIXME: We can do better than this by using selccz to choose between -0 and -2 398; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] 399; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] 400; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 401 402define i64 @slti64_1(i64 %a) { 403entry: 404 %cmp = icmp sgt i64 %a, 32767 405 %conv = select i1 %cmp, i64 5, i64 4 406 ret i64 %conv 407} 408 409; ALL-LABEL: slti64_2: 410 411; FIXME: The 32-bit versions of this test are too complicated to reasonably 412; match at the moment. They do show some missing optimizations though 413; such as: 414; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c) 415 416; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 417; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4 418; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 419; 64-CMOV-DAG: movz $[[I4]], $[[I3]], $[[R0]] 420 421; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 422; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 423; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 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]+]], $[[I3]], $[[R0]] 427; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]] 428; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 429 430define i64 @slti64_2(i64 %a) { 431entry: 432 %cmp = icmp sgt i64 %a, -32769 433 %conv = select i1 %cmp, i64 3, i64 4 434 ret i64 %conv 435} 436 437; ALL-LABEL: slti64_3: 438 439; FIXME: The 32-bit versions of this test are too complicated to reasonably 440; match at the moment. They do show some missing optimizations though 441; such as: 442; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c) 443 444; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 445; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4 446; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766 447; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 448; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]] 449 450; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 451; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4 452; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766 453; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 454; FIXME: We can do better than this by using selccz to choose between -0 and -2 455; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] 456; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] 457; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 458 459define i64 @slti64_3(i64 %a) { 460entry: 461 %cmp = icmp sgt i64 %a, -32770 462 %conv = select i1 %cmp, i64 5, i64 4 463 ret i64 %conv 464} 465 466; sltiu instructions. 467 468; ALL-LABEL: sltiu0: 469 470; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 471; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 472; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 473; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 474 475; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 476; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 477; 32-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 478; FIXME: We can do better than this by using selccz to choose between +0 and +2 479; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 480; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 481; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 482 483; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 484; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 485; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 486; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] 487 488; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 489; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 490; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 491; FIXME: We can do better than this by using selccz to choose between +0 and +2 492; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] 493; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] 494; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 495 496define i32 @sltiu0(i32 %a) { 497entry: 498 %cmp = icmp ugt i32 %a, 32766 499 %cond = select i1 %cmp, i32 3, i32 5 500 ret i32 %cond 501} 502 503; ALL-LABEL: sltiu1: 504 505; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 506; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 507; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 508; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 509; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] 510 511; 32-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 512; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 513; 32-CMP-DAG: addiu $[[I32767:[0-9]+]], $zero, 32767 514; 32-CMP-DAG: sltu $[[R0:[0-9]+]], $[[I32767]], $4 515; FIXME: We can do better than this by using selccz to choose between -0 and -2 516; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] 517; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 518; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 519 520; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 521; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 522; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 523; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 524; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] 525 526; 64-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 527; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 528; 64-CMP-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 529; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 530; FIXME: We can do better than this by using selccz to choose between -0 and -2 531; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] 532; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 533; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 534 535define i32 @sltiu1(i32 %a) { 536entry: 537 %cmp = icmp ugt i32 %a, 32767 538 %cond = select i1 %cmp, i32 7, i32 5 539 ret i32 %cond 540} 541 542; ALL-LABEL: sltiu2: 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, -32768 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, -32768 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, -32768 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, -32768 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 @sltiu2(i32 %a) { 571entry: 572 %cmp = icmp ugt i32 %a, -32769 573 %cond = select i1 %cmp, i32 3, i32 5 574 ret i32 %cond 575} 576 577; ALL-LABEL: sltiu3: 578 579; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 580; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 581; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 582; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 583; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 584; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] 585 586; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 587; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 588; 32-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 589; 32-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 590; 32-CMP-DAG: sltu $[[R0:[0-9]+]], $[[I32767]], $4 591; FIXME: We can do better than this by using selccz to choose between -0 and -2 592; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] 593; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 594; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] 595 596; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 597; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 598; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 599; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 600; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 601; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] 602 603; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 604; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 605; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 606; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 607; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[IMM]], $4 608; FIXME: We can do better than this by using selccz to choose between -0 and -2 609; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] 610; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] 611; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] 612 613define i32 @sltiu3(i32 %a) { 614entry: 615 %cmp = icmp ugt i32 %a, -32770 616 %cond = select i1 %cmp, i32 3, i32 5 617 ret i32 %cond 618} 619 620; Check if 621; (select (setxx a, N), x, x-1) or 622; (select (setxx a, N), x-1, x) 623; doesn't generate conditional moves 624; for constant operands whose difference is |1| 625 626define i32 @slti4(i32 %a) nounwind readnone { 627 %1 = icmp slt i32 %a, 7 628 %2 = select i1 %1, i32 4, i32 3 629 ret i32 %2 630} 631 632; ALL-LABEL: slti4: 633 634; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 635; 32-CMOV-DAG: addiu $2, [[R1]], 3 636; 32-CMOV-NOT: movn 637 638; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 639; 32-CMP-DAG: addiu $2, [[R1]], 3 640; 32-CMP-NOT: seleqz 641; 32-CMP-NOT: selnez 642 643; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 644; 64-CMOV-DAG: addiu $2, [[R1]], 3 645; 64-CMOV-NOT: movn 646 647; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 648; 64-CMP-DAG: addiu $2, [[R1]], 3 649; 64-CMP-NOT: seleqz 650; 64-CMP-NOT: selnez 651 652define i32 @slti5(i32 %a) nounwind readnone { 653 %1 = icmp slt i32 %a, 7 654 %2 = select i1 %1, i32 -3, i32 -4 655 ret i32 %2 656} 657 658; ALL-LABEL: slti5: 659 660; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 661; 32-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 662; 32-CMOV-NOT: movn 663 664; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 665; 32-CMP-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 666; 32-CMP-NOT: seleqz 667; 32-CMP-NOT: selnez 668 669; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 670; 64-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 671; 64-CMOV-NOT: movn 672 673; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 674; 64-CMP-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 675; 64-CMP-NOT: seleqz 676; 64-CMP-NOT: selnez 677 678define i32 @slti6(i32 %a) nounwind readnone { 679 %1 = icmp slt i32 %a, 7 680 %2 = select i1 %1, i32 3, i32 4 681 ret i32 %2 682} 683 684; ALL-LABEL: slti6: 685 686; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 687; 32-CMOV-DAG: xori [[R1]], [[R1]], 1 688; 32-CMOV-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 689; 32-CMOV-NOT: movn 690 691; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 692; 32-CMP-DAG: xori [[R1]], [[R1]], 1 693; 32-CMP-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 694; 32-CMP-NOT: seleqz 695; 32-CMP-NOT: selnez 696 697; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 698; 64-CMOV-DAG: xori [[R1]], [[R1]], 1 699; 64-CMOV-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 700; 64-CMOV-NOT: movn 701 702; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 703; 64-CMP-DAG: xori [[R1]], [[R1]], 1 704; 64-CMP-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 705; 64-CMP-NOT: seleqz 706; 64-CMP-NOT: selnez 707