Skip to content

Commit 259321e

Browse files
committed
[InstCombine] Drop Range attribute when simplifying 'fshl' based on demanded bits
When simplifying operands based on demanded bits, the return value range of llvm.fshl might change. Keeping the Range attribute might cause llvm.fshl to generate a poison and lead to miscompile (#124387). Drop the Range attribute similar to `dropPosonGeneratingFlags` elsewhere.
1 parent 942bd38 commit 259321e

File tree

2 files changed

+8
-4
lines changed

2 files changed

+8
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,11 +1039,14 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
10391039
APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
10401040
APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
10411041
if (I->getOperand(0) != I->getOperand(1)) {
1042-
if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown,
1043-
Depth + 1, Q) ||
1042+
if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1,
1043+
Q) ||
10441044
SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1,
1045-
Q))
1045+
Q)) {
1046+
// Range attribute may not longer hold.
1047+
I->dropPoisonGeneratingReturnAttributes();
10461048
return I;
1049+
}
10471050
} else { // fshl is a rotate
10481051
// Avoid converting rotate into funnel shift.
10491052
// Only simplify if one operand is constant.

llvm/test/Transforms/InstCombine/fsh.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,11 +1069,12 @@ entry:
10691069
ret <2 x i31> %res
10701070
}
10711071

1072+
;; #124387 Range attribute no longer holds after operands changed.
10721073
define i8 @fshl_range_trunc(i1 %x) {
10731074
; CHECK-LABEL: @fshl_range_trunc(
10741075
; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[X:%.*]] to i32
10751076
; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[ZEXT]], 126
1076-
; CHECK-NEXT: [[FSHL:%.*]] = call range(i32 -4, 2) i32 @llvm.fshl.i32(i32 [[OR]], i32 -2, i32 1)
1077+
; CHECK-NEXT: [[FSHL:%.*]] = call i32 @llvm.fshl.i32(i32 [[OR]], i32 -2, i32 1)
10771078
; CHECK-NEXT: [[TR:%.*]] = trunc nuw i32 [[FSHL]] to i8
10781079
; CHECK-NEXT: ret i8 [[TR]]
10791080
;

0 commit comments

Comments
 (0)