diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -1061,17 +1061,22 @@ if (Depth == 0) return false; switch (I->getOpcode()) { + case Instruction::UDiv: + case Instruction::SDiv: + case Instruction::FDiv: + case Instruction::URem: + case Instruction::SRem: + // Avoid introducing integer div/rem by undef to avoid undefined behavior. + for (int i = 0, e = Mask.size(); i != e; ++i) + if (Mask[i] == -1) + return false; + LLVM_FALLTHROUGH; case Instruction::Add: case Instruction::FAdd: case Instruction::Sub: case Instruction::FSub: case Instruction::Mul: case Instruction::FMul: - case Instruction::UDiv: - case Instruction::SDiv: - case Instruction::FDiv: - case Instruction::URem: - case Instruction::SRem: case Instruction::FRem: case Instruction::Shl: case Instruction::LShr: diff --git a/llvm/test/Transforms/InstCombine/shufflevector-div-rem.ll b/llvm/test/Transforms/InstCombine/shufflevector-div-rem.ll --- a/llvm/test/Transforms/InstCombine/shufflevector-div-rem.ll +++ b/llvm/test/Transforms/InstCombine/shufflevector-div-rem.ll @@ -8,7 +8,12 @@ ; extracting the second element in the vector). define i16 @test1(i16 %a, i1 %cmp) { ; CHECK-LABEL: @test1( -; CHECK-NEXT: ret i16 1 +; CHECK-NEXT: [[SPLATINSERT:%.*]] = insertelement <2 x i16> undef, i16 [[A:%.*]], i32 0 +; CHECK-NEXT: [[TMP1:%.*]] = srem <2 x i16> [[SPLATINSERT]], +; CHECK-NEXT: [[SPLAT_OP:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> undef, <2 x i32> +; CHECK-NEXT: [[T2:%.*]] = select i1 [[CMP:%.*]], <2 x i16> , <2 x i16> [[SPLAT_OP]] +; CHECK-NEXT: [[T3:%.*]] = extractelement <2 x i16> [[T2]], i32 1 +; CHECK-NEXT: ret i16 [[T3]] ; %splatinsert = insertelement <2 x i16> undef, i16 %a, i32 0 %splat = shufflevector <2 x i16> %splatinsert, <2 x i16> undef, <2 x i32> zeroinitializer @@ -23,7 +28,11 @@ ; transform the shufflevector by doing "evaluateInDifferentElementOrder". define <2 x i16> @test2(i16 %a, i1 %cmp) { ; CHECK-LABEL: @test2( -; CHECK-NEXT: ret <2 x i16> +; CHECK-NEXT: [[SPLATINSERT:%.*]] = insertelement <2 x i16> undef, i16 [[A:%.*]], i32 0 +; CHECK-NEXT: [[T1:%.*]] = srem <2 x i16> [[SPLATINSERT]], +; CHECK-NEXT: [[SPLAT_OP:%.*]] = shufflevector <2 x i16> [[T1]], <2 x i16> undef, <2 x i32> +; CHECK-NEXT: [[T2:%.*]] = select i1 [[CMP:%.*]], <2 x i16> , <2 x i16> [[SPLAT_OP]] +; CHECK-NEXT: ret <2 x i16> [[T2]] ; %splatinsert = insertelement <2 x i16> undef, i16 %a, i32 0 %t1 = srem <2 x i16> %splatinsert,