Index: llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -1919,7 +1919,8 @@ // max unsigned value. In that case, the remainder is 0: // urem Op0, (sext i1 X) --> (Op0 == -1) ? 0 : Op0 Value *X; - if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) { + if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1) && + isGuaranteedNotToBeUndefOrPoison(Op0)) { Value *Cmp = Builder.CreateICmpEQ(Op0, ConstantInt::getAllOnesValue(Ty)); return SelectInst::Create(Cmp, ConstantInt::getNullValue(Ty), Op0); } Index: llvm/test/Transforms/InstCombine/rem.ll =================================================================== --- llvm/test/Transforms/InstCombine/rem.ll +++ llvm/test/Transforms/InstCombine/rem.ll @@ -66,8 +66,8 @@ define i8 @urem_with_sext_bool_divisor(i1 %x, i8 %y) { ; CHECK-LABEL: @urem_with_sext_bool_divisor( -; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], -1 -; CHECK-NEXT: [[REM:%.*]] = select i1 [[TMP1]], i8 0, i8 [[Y]] +; CHECK-NEXT: [[S:%.*]] = sext i1 [[X:%.*]] to i8 +; CHECK-NEXT: [[REM:%.*]] = urem i8 [[Y:%.*]], [[S]] ; CHECK-NEXT: ret i8 [[REM]] ; %s = sext i1 %x to i8 @@ -77,8 +77,8 @@ define <2 x i8> @urem_with_sext_bool_divisor_vec(<2 x i1> %x, <2 x i8> %y) { ; CHECK-LABEL: @urem_with_sext_bool_divisor_vec( -; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[Y:%.*]], -; CHECK-NEXT: [[REM:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> zeroinitializer, <2 x i8> [[Y]] +; CHECK-NEXT: [[S:%.*]] = sext <2 x i1> [[X:%.*]] to <2 x i8> +; CHECK-NEXT: [[REM:%.*]] = urem <2 x i8> [[Y:%.*]], [[S]] ; CHECK-NEXT: ret <2 x i8> [[REM]] ; %s = sext <2 x i1> %x to <2 x i8> @@ -1020,3 +1020,15 @@ %r = urem i32 %x, %s ret i32 %r } + +; negative test +define <2 x i32> @PR62401(<2 x i1> %x, <2 x i32> %y) { +; CHECK-LABEL: @PR62401( +; CHECK-NEXT: [[SEXT_I1:%.*]] = sext <2 x i1> [[X:%.*]] to <2 x i32> +; CHECK-NEXT: [[R:%.*]] = urem <2 x i32> [[Y:%.*]], [[SEXT_I1]] +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %sext.i1 = sext <2 x i1> %x to <2 x i32> + %r = urem <2 x i32> %y, %sext.i1 + ret <2 x i32> %r +} Index: llvm/test/Transforms/InstCombine/shift.ll =================================================================== --- llvm/test/Transforms/InstCombine/shift.ll +++ llvm/test/Transforms/InstCombine/shift.ll @@ -1713,12 +1713,12 @@ ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i64 -1, i64 -2 ; CHECK-NEXT: [[G11:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP2]] ; CHECK-NEXT: [[L7:%.*]] = load i177, ptr [[G11]], align 4 +; CHECK-NEXT: [[B6:%.*]] = sext i1 [[TMP1]] to i177 ; CHECK-NEXT: [[C171:%.*]] = icmp slt i177 [[L7]], 0 ; CHECK-NEXT: [[C17:%.*]] = select i1 [[TMP1]], i1 [[C171]], i1 false ; CHECK-NEXT: [[TMP3:%.*]] = sext i1 [[C17]] to i64 ; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP3]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i177 [[L7]], -1 -; CHECK-NEXT: [[B28:%.*]] = select i1 [[TMP4]], i177 0, i177 [[L7]] +; CHECK-NEXT: [[B28:%.*]] = urem i177 [[L7]], [[B6]] ; CHECK-NEXT: store i177 [[B28]], ptr [[G62]], align 4 ; CHECK-NEXT: ret void ;