diff --git a/llvm/lib/Target/RISCV/RISCVCodeGenPrepare.cpp b/llvm/lib/Target/RISCV/RISCVCodeGenPrepare.cpp index 6434532afd409..53fcc527e615d 100644 --- a/llvm/lib/Target/RISCV/RISCVCodeGenPrepare.cpp +++ b/llvm/lib/Target/RISCV/RISCVCodeGenPrepare.cpp @@ -21,6 +21,7 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstVisitor.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/PatternMatch.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" @@ -67,20 +68,13 @@ bool RISCVCodeGenPrepare::visitAnd(BinaryOperator &BO) { if (!BO.getType()->isIntegerTy(64)) return false; - auto canBeSignExtend = [](Instruction *I) { - if (isa(I)) - return true; - if (isa(I)) - return I->hasNonNeg(); - return false; - }; + using namespace PatternMatch; - // Left hand side should be a sext or zext nneg. - Instruction *LHS = dyn_cast(BO.getOperand(0)); - if (!LHS || !canBeSignExtend(LHS)) + // Left hand side should be a zext nneg. + Value *LHSSrc; + if (!match(BO.getOperand(0), m_NNegZExt(m_Value(LHSSrc)))) return false; - Value *LHSSrc = LHS->getOperand(0); if (!LHSSrc->getType()->isIntegerTy(32)) return false; @@ -100,7 +94,7 @@ bool RISCVCodeGenPrepare::visitAnd(BinaryOperator &BO) { // Sign extend the constant and replace the And operand. C = SignExtend64<32>(C); - BO.setOperand(1, ConstantInt::get(LHS->getType(), C)); + BO.setOperand(1, ConstantInt::get(RHS->getType(), C)); return true; } diff --git a/llvm/test/CodeGen/RISCV/riscv-codegenprepare.ll b/llvm/test/CodeGen/RISCV/riscv-codegenprepare.ll index 0e4e04af4a3fe..2179a0d26cf98 100644 --- a/llvm/test/CodeGen/RISCV/riscv-codegenprepare.ll +++ b/llvm/test/CodeGen/RISCV/riscv-codegenprepare.ll @@ -91,3 +91,15 @@ for.body: ; preds = %for.body, %for.body %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 } + +; Make sure we do not change 4294967295 to -1 here. +define i64 @bug(i32 %x) { +; CHECK-LABEL: @bug( +; CHECK-NEXT: [[A:%.*]] = sext i32 [[X:%.*]] to i64 +; CHECK-NEXT: [[B:%.*]] = and i64 [[A]], 4294967295 +; CHECK-NEXT: ret i64 [[B]] +; + %a = sext i32 %x to i64 + %b = and i64 %a, 4294967295 + ret i64 %b +}