263 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \3; RUN: | FileCheck %s -check-prefix=RV64I4 5; Test that we turn (sra (shl X, 32), 32-C) into (slli (sext.w X), C)6 7define i64 @test1(i64 %a) nounwind {8; RV64I-LABEL: test1:9; RV64I: # %bb.0:10; RV64I-NEXT: sext.w a0, a011; RV64I-NEXT: slli a0, a0, 212; RV64I-NEXT: ret13 %1 = shl i64 %a, 3214 %2 = ashr i64 %1, 3015 ret i64 %216}17 18define i64 @test2(i32 signext %a) nounwind {19; RV64I-LABEL: test2:20; RV64I: # %bb.0:21; RV64I-NEXT: slli a0, a0, 322; RV64I-NEXT: ret23 %1 = zext i32 %a to i6424 %2 = shl i64 %1, 3225 %3 = ashr i64 %2, 2926 ret i64 %327}28 29define i64 @test3(ptr %a) nounwind {30; RV64I-LABEL: test3:31; RV64I: # %bb.0:32; RV64I-NEXT: lw a0, 0(a0)33; RV64I-NEXT: slli a0, a0, 434; RV64I-NEXT: ret35 %1 = load i32, ptr %a36 %2 = zext i32 %1 to i6437 %3 = shl i64 %2, 3238 %4 = ashr i64 %3, 2839 ret i64 %440}41 42define i64 @test4(i32 signext %a, i32 signext %b) nounwind {43; RV64I-LABEL: test4:44; RV64I: # %bb.0:45; RV64I-NEXT: addw a0, a0, a146; RV64I-NEXT: slli a0, a0, 3047; RV64I-NEXT: ret48 %1 = add i32 %a, %b49 %2 = zext i32 %1 to i6450 %3 = shl i64 %2, 3251 %4 = ashr i64 %3, 252 ret i64 %453}54 55define i64 @test5(i32 signext %a, i32 signext %b) nounwind {56; RV64I-LABEL: test5:57; RV64I: # %bb.0:58; RV64I-NEXT: xor a0, a0, a159; RV64I-NEXT: slli a0, a0, 3160; RV64I-NEXT: ret61 %1 = xor i32 %a, %b62 %2 = zext i32 %1 to i6463 %3 = shl i64 %2, 3264 %4 = ashr i64 %3, 165 ret i64 %466}67 68define i64 @test6(i32 signext %a, i32 signext %b) nounwind {69; RV64I-LABEL: test6:70; RV64I: # %bb.0:71; RV64I-NEXT: sllw a0, a0, a172; RV64I-NEXT: slli a0, a0, 1673; RV64I-NEXT: ret74 %1 = shl i32 %a, %b75 %2 = zext i32 %1 to i6476 %3 = shl i64 %2, 3277 %4 = ashr i64 %3, 1678 ret i64 %479}80 81; The ashr+add+shl is canonical IR from InstCombine for82; (sext (add (trunc X to i32), 1) to i32).83; That can be implemented as addiw make sure we recover it.84define i64 @test7(ptr %0, i64 %1) {85; RV64I-LABEL: test7:86; RV64I: # %bb.0:87; RV64I-NEXT: addiw a0, a1, 188; RV64I-NEXT: ret89 %3 = shl i64 %1, 3290 %4 = add i64 %3, 429496729691 %5 = ashr exact i64 %4, 3292 ret i64 %593}94 95; The ashr+add+shl is canonical IR from InstCombine for96; (sext (sub 1, (trunc X to i32)) to i32).97; That can be implemented as (li 1)+subw make sure we recover it.98define i64 @test8(ptr %0, i64 %1) {99; RV64I-LABEL: test8:100; RV64I: # %bb.0:101; RV64I-NEXT: li a0, 1102; RV64I-NEXT: subw a0, a0, a1103; RV64I-NEXT: ret104 %3 = mul i64 %1, -4294967296105 %4 = add i64 %3, 4294967296106 %5 = ashr exact i64 %4, 32107 ret i64 %5108}109 110; The gep is here to introduce a shl by 2 after the ashr that will get folded111; and make this harder to recover.112define signext i32 @test9(ptr %0, i64 %1) {113; RV64I-LABEL: test9:114; RV64I: # %bb.0:115; RV64I-NEXT: lui a2, 1116; RV64I-NEXT: addi a2, a2, 1117; RV64I-NEXT: addw a1, a1, a2118; RV64I-NEXT: slli a1, a1, 2119; RV64I-NEXT: add a0, a0, a1120; RV64I-NEXT: lw a0, 0(a0)121; RV64I-NEXT: ret122 %3 = shl i64 %1, 32123 %4 = add i64 %3, 17596481011712 ; 4097 << 32124 %5 = ashr exact i64 %4, 32125 %6 = getelementptr inbounds i32, ptr %0, i64 %5126 %7 = load i32, ptr %6, align 4127 ret i32 %7128}129 130; The gep is here to introduce a shl by 2 after the ashr that will get folded131; and make this harder to recover.132define signext i32 @test10(ptr %0, i64 %1) {133; RV64I-LABEL: test10:134; RV64I: # %bb.0:135; RV64I-NEXT: lui a2, 30141136; RV64I-NEXT: addi a2, a2, -747137; RV64I-NEXT: subw a2, a2, a1138; RV64I-NEXT: slli a2, a2, 2139; RV64I-NEXT: add a0, a0, a2140; RV64I-NEXT: lw a0, 0(a0)141; RV64I-NEXT: ret142 %3 = mul i64 %1, -4294967296143 %4 = add i64 %3, 530242871224172544 ; 123456789 << 32144 %5 = ashr exact i64 %4, 32145 %6 = getelementptr inbounds i32, ptr %0, i64 %5146 %7 = load i32, ptr %6, align 4147 ret i32 %7148}149 150define i64 @test11(ptr %0, i64 %1) {151; RV64I-LABEL: test11:152; RV64I: # %bb.0:153; RV64I-NEXT: lui a0, 524288154; RV64I-NEXT: subw a0, a0, a1155; RV64I-NEXT: ret156 %3 = mul i64 %1, -4294967296157 %4 = add i64 %3, 9223372036854775808 ;0x8000'0000'0000'0000158 %5 = ashr exact i64 %4, 32159 ret i64 %5160}161 162; Make sure we use slli+srai to enable the possibility of compressed163define i32 @test12(i32 signext %0) {164; RV64I-LABEL: test12:165; RV64I: # %bb.0:166; RV64I-NEXT: slli a0, a0, 49167; RV64I-NEXT: srai a0, a0, 47168; RV64I-NEXT: ret169 %2 = shl i32 %0, 17170 %3 = ashr i32 %2, 15171 ret i32 %3172}173 174define i8 @test13(ptr %0, i64 %1) {175; RV64I-LABEL: test13:176; RV64I: # %bb.0:177; RV64I-NEXT: li a2, 1178; RV64I-NEXT: li a3, 2179; RV64I-NEXT: subw a2, a2, a1180; RV64I-NEXT: subw a3, a3, a1181; RV64I-NEXT: add a2, a0, a2182; RV64I-NEXT: add a0, a0, a3183; RV64I-NEXT: lbu a1, 0(a2)184; RV64I-NEXT: lbu a0, 0(a0)185; RV64I-NEXT: add a0, a1, a0186; RV64I-NEXT: ret187 %3 = mul i64 %1, -4294967296188 %4 = add i64 %3, 4294967296 ; 1 << 32189 %5 = ashr exact i64 %4, 32190 %6 = getelementptr inbounds i8, ptr %0, i64 %5191 %7 = load i8, ptr %6, align 4192 %8 = add i64 %3, 8589934592 ; 2 << 32193 %9 = ashr exact i64 %8, 32194 %10 = getelementptr inbounds i8, ptr %0, i64 %9195 %11 = load i8, ptr %10, align 4196 %12 = add i8 %7, %11197 ret i8 %12198}199 200define signext i32 @test14(ptr %0, ptr %1, i64 %2) {201; RV64I-LABEL: test14:202; RV64I: # %bb.0:203; RV64I-NEXT: li a3, 1204; RV64I-NEXT: subw a3, a3, a2205; RV64I-NEXT: add a0, a0, a3206; RV64I-NEXT: slli a3, a3, 2207; RV64I-NEXT: lbu a0, 0(a0)208; RV64I-NEXT: add a1, a1, a3209; RV64I-NEXT: lw a1, 0(a1)210; RV64I-NEXT: addw a0, a0, a1211; RV64I-NEXT: ret212 %4 = mul i64 %2, -4294967296213 %5 = add i64 %4, 4294967296 ; 1 << 32214 %6 = ashr exact i64 %5, 32215 %7 = getelementptr inbounds i8, ptr %0, i64 %6216 %8 = load i8, ptr %7, align 4217 %9 = zext i8 %8 to i32218 %10 = getelementptr inbounds i32, ptr %1, i64 %6219 %11 = load i32, ptr %10, align 4220 %12 = add i32 %9, %11221 ret i32 %12222}223 224; Test that we can propagate sign bits through sraw. We should use an slli225; instead of slliw.226define signext i32 @test15(i32 signext %x, i32 signext %y) {227; RV64I-LABEL: test15:228; RV64I: # %bb.0:229; RV64I-NEXT: srli a0, a0, 1230; RV64I-NEXT: sraw a0, a0, a1231; RV64I-NEXT: slli a0, a0, 1232; RV64I-NEXT: ret233 %a = ashr i32 %x, 1234 %b = ashr i32 %a, %y235 %c = shl i32 %b, 1236 ret i32 %c237}238 239define signext i32 @test16(i32 signext %x, i32 signext %y) {240; RV64I-LABEL: test16:241; RV64I: # %bb.0:242; RV64I-NEXT: ori a2, a0, 192243; RV64I-NEXT: srli a3, a0, 8244; RV64I-NEXT: lui a4, 16245; RV64I-NEXT: srliw a0, a0, 24246; RV64I-NEXT: addi a4, a4, -256247; RV64I-NEXT: and a3, a3, a4248; RV64I-NEXT: and a4, a2, a4249; RV64I-NEXT: or a0, a3, a0250; RV64I-NEXT: slli a4, a4, 8251; RV64I-NEXT: slli a2, a2, 24252; RV64I-NEXT: or a2, a2, a4253; RV64I-NEXT: or a0, a2, a0254; RV64I-NEXT: sraw a0, a0, a1255; RV64I-NEXT: slli a0, a0, 1256; RV64I-NEXT: ret257 %a = or i32 %x, 192258 %d = call i32 @llvm.bswap.i32(i32 %a)259 %b = ashr i32 %d, %y260 %c = shl i32 %b, 1261 ret i32 %c262}263