diff --git a/llvm/lib/Target/RISCV/RISCVCodeGenPrepare.cpp b/llvm/lib/Target/RISCV/RISCVCodeGenPrepare.cpp --- a/llvm/lib/Target/RISCV/RISCVCodeGenPrepare.cpp +++ b/llvm/lib/Target/RISCV/RISCVCodeGenPrepare.cpp @@ -29,6 +29,8 @@ #define PASS_NAME "RISCV CodeGenPrepare" STATISTIC(NumZExtToSExt, "Number of SExt instructions converted to ZExt"); +STATISTIC(NumZExtToSExtNonNeg, + "Number of SExt non negative value instructions converted to ZExt"); namespace { @@ -36,7 +38,6 @@ public InstVisitor { const DataLayout *DL; const RISCVSubtarget *ST; - public: static char ID; @@ -84,6 +85,17 @@ return true; } + // Look for zext instructions that have the nneg flag. + if (ZExt.hasNonNeg()){ + auto SExt = new SExtInst(Src, ZExt.getType(), "", &ZExt); + SExt->takeName(&ZExt); + SExt->setDebugLoc(ZExt.getDebugLoc()); + + ZExt.replaceAllUsesWith(SExt); + ZExt.eraseFromParent(); + ++NumZExtToSExtNonNeg; + return true; + } // Convert (zext (abs(i32 X, i1 1))) -> (sext (abs(i32 X, i1 1))). If abs of // INT_MIN is poison, the sign bit is zero. using namespace PatternMatch; @@ -158,7 +170,6 @@ ST = &TM.getSubtarget(F); DL = &F.getParent()->getDataLayout(); - bool MadeChange = false; for (auto &BB : F) for (Instruction &I : llvm::make_early_inc_range(BB)) diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll --- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll +++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=riscv32 -O3 -debug-pass=Structure < %s -o /dev/null 2>&1 | \ ; RUN: grep -v "Verify generated machine code" | \ ; RUN: FileCheck %s --check-prefixes=CHECK diff --git a/llvm/test/CodeGen/RISCV/riscv-codegenprepare-asm.ll b/llvm/test/CodeGen/RISCV/riscv-codegenprepare-asm.ll --- a/llvm/test/CodeGen/RISCV/riscv-codegenprepare-asm.ll +++ b/llvm/test/CodeGen/RISCV/riscv-codegenprepare-asm.ll @@ -125,3 +125,15 @@ %niter.ncmp.1 = icmp eq i64 %niter.next.1, %unroll_iter br i1 %niter.ncmp.1, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body } + +define i64 @test3(i32 noundef %a){ +; CHECK-LABEL: test3: +; CHECK: # %bb.0: +; CHECK-NEXT: sext.w a0, a0 +; CHECK-NEXT: addi a0, a0, 5 +; CHECK-NEXT: ret + + %ext = zext nneg i32 %a to i64 + %added = add i64 %ext, 5 + ret i64 %added +} diff --git a/llvm/test/CodeGen/RISCV/riscv-codegenprepare.ll b/llvm/test/CodeGen/RISCV/riscv-codegenprepare.ll --- a/llvm/test/CodeGen/RISCV/riscv-codegenprepare.ll +++ b/llvm/test/CodeGen/RISCV/riscv-codegenprepare.ll @@ -142,3 +142,29 @@ %niter.ncmp.1 = icmp eq i64 %niter.next.1, %unroll_iter br i1 %niter.ncmp.1, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body } + +declare void @llvm.assume(i1 %assume); +define i64 @test3(i32 noundef signext %a){ +; CHECK-LABEL: @test3( +; CHECK-NEXT: [[ASSUME:%.*]] = icmp sge i32 [[A:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]]) +; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[A]] to i64 +; CHECK-NEXT: ret i64 [[EXT]] +; + %assume = icmp sge i32 %a, 0; + call void @llvm.assume(i1 %assume) + %ext = zext i32 %a to i64 + ret i64 %ext +} + + +define i64 @test4(i32 noundef signext %a){ +; CHECK-LABEL: @test4( +; CHECK-NEXT: [[EXT:%.*]] = sext i32 [[A:%.*]] to i64 +; CHECK-NEXT: ret i64 [[EXT]] +; + %ext = zext nneg i32 %a to i64; + ret i64 %ext; +} + +