Skip to content

Commit 534f856

Browse files
committed
[InstCombine] Don't preserve context across div
We can't preserve the context across a non-speculatable instruction, as this might introduce a trap. Alternatively, we could also insert all the replacement instruction at the use-site, but that would be a more intrusive change for the sake of this edge case. Fixes #95547.
1 parent 7767f0d commit 534f856

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,12 @@ static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC,
291291
uint32_t BitWidth = Ty->getScalarSizeInBits();
292292
assert(BitWidth < OrigBitWidth && "Unexpected bitwidths!");
293293
APInt Mask = APInt::getBitsSetFrom(OrigBitWidth, BitWidth);
294-
if (IC.MaskedValueIsZero(I->getOperand(0), Mask, 0, CxtI) &&
295-
IC.MaskedValueIsZero(I->getOperand(1), Mask, 0, CxtI)) {
296-
return canEvaluateTruncated(I->getOperand(0), Ty, IC, CxtI) &&
297-
canEvaluateTruncated(I->getOperand(1), Ty, IC, CxtI);
294+
// Do not preserve the original context instruction. Simplifying div/rem
295+
// based on later context may introduce a trap.
296+
if (IC.MaskedValueIsZero(I->getOperand(0), Mask, 0, I) &&
297+
IC.MaskedValueIsZero(I->getOperand(1), Mask, 0, I)) {
298+
return canEvaluateTruncated(I->getOperand(0), Ty, IC, I) &&
299+
canEvaluateTruncated(I->getOperand(1), Ty, IC, I);
298300
}
299301
break;
300302
}

llvm/test/Transforms/InstCombine/trunc.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,15 +1097,15 @@ define <2 x i1> @trunc_nuw_xor_vector(<2 x i8> %x, <2 x i8> %y) {
10971097
ret <2 x i1> %r
10981098
}
10991099

1100-
; FIXME: This is a miscompile.
11011100
define void @pr95547(i32 %x) {
11021101
; CHECK-LABEL: @pr95547(
1103-
; CHECK-NEXT: [[X_TRUNC:%.*]] = trunc i32 [[X:%.*]] to i8
1104-
; CHECK-NEXT: [[DIV:%.*]] = udiv i8 11, [[X_TRUNC]]
1102+
; CHECK-NEXT: [[X_TRUNC:%.*]] = trunc i32 [[X:%.*]] to i16
1103+
; CHECK-NEXT: [[DIV:%.*]] = udiv i16 11, [[X_TRUNC]]
11051104
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], 256
11061105
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP:%.*]], label [[EXIT:%.*]]
11071106
; CHECK: loop:
1108-
; CHECK-NEXT: call void @use.i8(i8 [[DIV]])
1107+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw nsw i16 [[DIV]] to i8
1108+
; CHECK-NEXT: call void @use.i8(i8 [[TRUNC]])
11091109
; CHECK-NEXT: br label [[LOOP]]
11101110
; CHECK: exit:
11111111
; CHECK-NEXT: ret void

0 commit comments

Comments
 (0)