Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -1055,9 +1055,11 @@ // If this is a boolean op (single-bit element type), we can't have // division-by-zero or remainder-by-zero, so assume the divisor is 1. // Similarly, if we're zero-extending a boolean divisor, then assume it's a 1. + // If this is an integer remainder (1 % Y), assume similarly the divisor is 1. Value *X; if (match(Op1, m_One()) || Ty->isIntOrIntVectorTy(1) || - (match(Op1, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))) + (match(Op1, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) || + match(Op1, m_IRem(m_One(), m_Value()))) return IsDiv ? Op0 : Constant::getNullValue(Ty); // If X * Y does not overflow, then: Index: llvm/test/Transforms/InstSimplify/div.ll =================================================================== --- llvm/test/Transforms/InstSimplify/div.ll +++ llvm/test/Transforms/InstSimplify/div.ll @@ -434,3 +434,84 @@ } !0 = !{i32 0, i32 3} + +define i32 @sdiv_one_srem_divisor(i32 %a, i32 %b) { +; CHECK-LABEL: @sdiv_one_srem_divisor( +; CHECK-NEXT: ret i32 [[O:%.*]] +; + %srem = srem i32 1, %b + %sdiv = sdiv i32 %a, %srem + ret i32 %sdiv +} + +define i32 @sdiv_one_urem_divisor(i32 %a, i32 %b) { +; CHECK-LABEL: @sdiv_one_urem_divisor( +; CHECK-NEXT: ret i32 [[O:%.*]] +; + %urem = urem i32 1, %b + %sdiv = sdiv i32 %a, %urem + ret i32 %sdiv +} + +define i32 @udiv_one_srem_divisor(i32 %a, i32 %b) { +; CHECK-LABEL: @udiv_one_srem_divisor( +; CHECK-NEXT: ret i32 [[O:%.*]] +; + %srem = srem i32 1, %b + %udiv = udiv i32 %a, %srem + ret i32 %udiv +} + +define i32 @udiv_one_urem_divisor(i32 %a, i32 %b) { +; CHECK-LABEL: @udiv_one_urem_divisor( +; CHECK-NEXT: ret i32 [[O:%.*]] +; + %urem = urem i32 1, %b + %udiv = udiv i32 %a, %urem + ret i32 %udiv +} + +define i32 @srem_one_srem_divisor(i32 %a, i32 %b) { +; CHECK-LABEL: @srem_one_srem_divisor( +; CHECK-NEXT: ret i32 0 +; + %srem = srem i32 1, %b + %srem1 = srem i32 %a, %srem + ret i32 %srem1 +} + +define i32 @urem_one_srem_divisor(i32 %a, i32 %b) { +; CHECK-LABEL: @urem_one_srem_divisor( +; CHECK-NEXT: ret i32 0 +; + %srem = srem i32 1, %b + %urem = urem i32 %a, %srem + ret i32 %urem +} + +define i32 @srem_one_urem_divisor(i32 %a, i32 %b) { +; CHECK-LABEL: @srem_one_urem_divisor( +; CHECK-NEXT: ret i32 0 +; + %urem = urem i32 1, %b + %srem = srem i32 %a, %urem + ret i32 %srem +} + +define i32 @urem_one_urem_divisor(i32 %a, i32 %b) { +; CHECK-LABEL: @urem_one_urem_divisor( +; CHECK-NEXT: ret i32 0 +; + %urem = urem i32 1, %b + %urem1 = urem i32 %a, %urem + ret i32 %urem1 +} + +define <2 x i8> @sdiv_one_vec_srem_divisor(<2 x i8> %a, <2 x i8> %b) { +; CHECK-LABEL: @sdiv_one_vec_srem_divisor( +; CHECK-NEXT: ret <2 x i8> [[O:%.*]] +; + %srem = srem <2 x i8> , %b + %sdiv = sdiv <2 x i8> %a, %srem + ret <2 x i8> %sdiv +} \ No newline at end of file