Skip to content

Commit 525d00e

Browse files
committed
[InstCombine] Fix poison propagation in round up alignment fold
We can't directly use the high bits value if it is more poisonous due to poison elements in the masks. This fixes the issue reported in #88217 (comment).
1 parent 097b68f commit 525d00e

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2965,7 +2965,8 @@ foldRoundUpIntegerWithPow2Alignment(SelectInst &SI,
29652965
return nullptr;
29662966

29672967
if (!XBiasedHighBits->hasOneUse()) {
2968-
if (*BiasCst == *LowBitMaskCst)
2968+
// We can't directly return XBiasedHighBits if it is more poisonous.
2969+
if (*BiasCst == *LowBitMaskCst && impliesPoison(XBiasedHighBits, X))
29692970
return XBiasedHighBits;
29702971
return nullptr;
29712972
}

llvm/test/Transforms/InstCombine/integer-round-up-pow2-alignment.ll

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -437,14 +437,17 @@ define i8 @t17_oneuse(i8 %x) {
437437
ret i8 %x.roundedup
438438
}
439439

440-
; Bias is equal to the alignment-1 (as opposed to alignment),
441-
; so we can just replace %x.roundedup with %x.biased.highbits
440+
; Negative test: We can't replace with %x.biased.highbits because it is
441+
; more poisonous.
442442
define <2 x i4> @t18_replacement_0b0001(<2 x i4> %x) {
443443
; CHECK-LABEL: @t18_replacement_0b0001(
444-
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X:%.*]], <i4 3, i4 3>
444+
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 3>
445+
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[X_LOWBITS]], zeroinitializer
446+
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X]], <i4 3, i4 3>
445447
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i4> [[X_BIASED]], <i4 -4, i4 poison>
446448
; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]])
447-
; CHECK-NEXT: ret <2 x i4> [[X_BIASED_HIGHBITS]]
449+
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i4> [[X]], <2 x i4> [[X_BIASED_HIGHBITS]]
450+
; CHECK-NEXT: ret <2 x i4> [[X_ROUNDEDUP]]
448451
;
449452
%x.lowbits = and <2 x i4> %x, <i4 3, i4 3>
450453
%x.lowbits.are.zero = icmp eq <2 x i4> %x.lowbits, <i4 0, i4 0>
@@ -454,12 +457,17 @@ define <2 x i4> @t18_replacement_0b0001(<2 x i4> %x) {
454457
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i4> %x, <2 x i4> %x.biased.highbits
455458
ret <2 x i4> %x.roundedup
456459
}
460+
; Negative test: We can't replace with %x.biased.highbits because it is
461+
; more poisonous.
457462
define <2 x i4> @t18_replacement_0b0010(<2 x i4> %x) {
458463
; CHECK-LABEL: @t18_replacement_0b0010(
459-
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X:%.*]], <i4 3, i4 poison>
464+
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 3>
465+
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[X_LOWBITS]], zeroinitializer
466+
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X]], <i4 3, i4 poison>
460467
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i4> [[X_BIASED]], <i4 -4, i4 -4>
461468
; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]])
462-
; CHECK-NEXT: ret <2 x i4> [[X_BIASED_HIGHBITS]]
469+
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i4> [[X]], <2 x i4> [[X_BIASED_HIGHBITS]]
470+
; CHECK-NEXT: ret <2 x i4> [[X_ROUNDEDUP]]
463471
;
464472
%x.lowbits = and <2 x i4> %x, <i4 3, i4 3>
465473
%x.lowbits.are.zero = icmp eq <2 x i4> %x.lowbits, <i4 0, i4 0>

0 commit comments

Comments
 (0)