diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 9ef6a0e94c24..b5b8aa332676 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -640,16 +640,16 @@ static Value *foldSelectICmpAnd(const SelectInst &SI, const ICmpInst *IC, unsigned AndZeros = AndRHS->getValue().logBase2(); // If types don't match we can still convert the select by introducing a zext - // or a trunc of the 'and'. The trunc case requires that all of the truncated - // bits are zero, we can figure that out by looking at the 'and' mask. - if (AndZeros >= ValC.getBitWidth()) - return nullptr; - - Value *V = Builder.CreateZExtOrTrunc(LHS, SI.getType()); - if (ValZeros > AndZeros) + // or a trunc of the 'and'. + Value *V = LHS; + if (ValZeros > AndZeros) { + V = Builder.CreateZExtOrTrunc(V, SI.getType()); V = Builder.CreateShl(V, ValZeros - AndZeros); - else if (ValZeros < AndZeros) + } else if (ValZeros < AndZeros) { V = Builder.CreateLShr(V, AndZeros - ValZeros); + V = Builder.CreateZExtOrTrunc(V, SI.getType()); + } else + V = Builder.CreateZExtOrTrunc(V, SI.getType()); // Okay, now we know that everything is set up, we just don't know whether we // have a icmp_ne or icmp_eq and whether the true or false val is the zero. diff --git a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll index f562c6ebafb0..c92a749f7249 100644 --- a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll +++ b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll @@ -256,11 +256,11 @@ define i32 @select_icmp_x_and_2147483648_ne_0_or_2147483648(i32 %x) { define i32 @test65(i64 %x) { ; CHECK-LABEL: @test65( -; CHECK-NEXT: [[X_TR:%.*]] = trunc i64 %x to i32 -; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X_TR]], 3 -; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 2 -; CHECK-NEXT: [[TMP3:%.*]] = xor i32 [[TMP2]], 42 -; CHECK-NEXT: ret i32 [[TMP3]] +; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 3 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 +; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 2 +; CHECK-NEXT: [[TMP4:%.*]] = xor i32 [[TMP3]], 42 +; CHECK-NEXT: ret i32 [[TMP4]] ; %1 = and i64 %x, 16 %2 = icmp ne i64 %1, 0 @@ -270,10 +270,11 @@ define i32 @test65(i64 %x) { define i32 @test66(i64 %x) { ; CHECK-LABEL: @test66( -; CHECK-NEXT: [[TMP1:%.*]] = and i64 %x, 4294967296 -; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 0 -; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 42, i32 40 -; CHECK-NEXT: ret i32 [[TMP3]] +; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 31 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 +; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 2 +; CHECK-NEXT: [[TMP4:%.*]] = xor i32 [[TMP3]], 42 +; CHECK-NEXT: ret i32 [[TMP4]] ; %1 = and i64 %x, 4294967296 %2 = icmp ne i64 %1, 0