Skip to content

Commit c090548

Browse files
authored
[InstCombine] Drop poison-generating flags when reusing existing or instruction (llvm#161504)
Closes llvm#161493.
1 parent 2e5a5fd commit c090548

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3080,6 +3080,13 @@ InstCombinerImpl::convertOrOfShiftsToFunnelShift(Instruction &Or) {
30803080
assert(ZextLowShlAmt->uge(HighSize) &&
30813081
ZextLowShlAmt->ule(Width - LowSize) && "Invalid concat");
30823082

3083+
// We cannot reuse the result if it may produce poison.
3084+
// Drop poison generating flags in the expression tree.
3085+
// Or
3086+
cast<Instruction>(U)->dropPoisonGeneratingFlags();
3087+
// Shl
3088+
cast<Instruction>(X)->dropPoisonGeneratingFlags();
3089+
30833090
FShiftArgs = {U, U, ConstantInt::get(Or0->getType(), *ZextHighShlAmt)};
30843091
break;
30853092
}

llvm/test/Transforms/InstCombine/funnel.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,3 +635,29 @@ define i32 @test_rotl_and_neg_wrong_mask(i32 %x, i32 %shamt) {
635635
%or = or i32 %shl, %shr
636636
ret i32 %or
637637
}
638+
639+
declare void @use(i16)
640+
641+
; Make sure the reused result does not produce poison.
642+
643+
define i16 @fshl_concat_vector_may_produce_poison(i4 %x, i12 %y) {
644+
; CHECK-LABEL: @fshl_concat_vector_may_produce_poison(
645+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X:%.*]]
646+
; CHECK-NEXT: [[ZEXT_X:%.*]] = zext i4 [[X_FR]] to i16
647+
; CHECK-NEXT: [[SLX:%.*]] = shl nuw i16 [[ZEXT_X]], 12
648+
; CHECK-NEXT: [[ZEXT_Y:%.*]] = zext i12 [[Y:%.*]] to i16
649+
; CHECK-NEXT: [[XY:%.*]] = or disjoint i16 [[SLX]], [[ZEXT_Y]]
650+
; CHECK-NEXT: call void @use(i16 [[XY]])
651+
; CHECK-NEXT: [[YX:%.*]] = call i16 @llvm.fshl.i16(i16 [[XY]], i16 [[XY]], i16 4)
652+
; CHECK-NEXT: ret i16 [[YX]]
653+
;
654+
%x.fr = freeze i4 %x
655+
%zext.x = zext i4 %x.fr to i16
656+
%slx = shl nuw nsw i16 %zext.x, 12
657+
%zext.y = zext i12 %y to i16
658+
%xy = or disjoint i16 %slx, %zext.y
659+
call void @use(i16 %xy)
660+
%sly = shl nuw i16 %zext.y, 4
661+
%yx = or disjoint i16 %sly, %zext.x
662+
ret i16 %yx
663+
}

0 commit comments

Comments
 (0)