[llvm] [InstCombine] Drop Range attribute when simplifying 'fshl' based on demanded bits (PR #124429)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 25 12:28:38 PST 2025
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/124429
>From 942bd381db30d2938407f6ad79991d5408ada73e Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sat, 25 Jan 2025 11:55:52 -0800
Subject: [PATCH 1/2] [InstCombine] Test incorrect retention of fshl range
---
llvm/test/Transforms/InstCombine/fsh.ll | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/fsh.ll b/llvm/test/Transforms/InstCombine/fsh.ll
index 236c69e7a5bcb7..34648d586300f0 100644
--- a/llvm/test/Transforms/InstCombine/fsh.ll
+++ b/llvm/test/Transforms/InstCombine/fsh.ll
@@ -1068,3 +1068,18 @@ entry:
%res = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> zeroinitializer, <2 x i31> %y)
ret <2 x i31> %res
}
+
+define i8 @fshl_range_trunc(i1 %x) {
+; CHECK-LABEL: @fshl_range_trunc(
+; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[X:%.*]] to i32
+; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[ZEXT]], 126
+; CHECK-NEXT: [[FSHL:%.*]] = call range(i32 -4, 2) i32 @llvm.fshl.i32(i32 [[OR]], i32 -2, i32 1)
+; CHECK-NEXT: [[TR:%.*]] = trunc nuw i32 [[FSHL]] to i8
+; CHECK-NEXT: ret i8 [[TR]]
+;
+ %zext = zext i1 %x to i32
+ %or = or disjoint i32 %zext, -2
+ %fshl = call range(i32 -4, 2) i32 @llvm.fshl.i32(i32 %or, i32 %or, i32 1)
+ %tr = trunc nsw i32 %fshl to i8
+ ret i8 %tr
+}
>From 259321eaae87edad5020e90103a3a8167f94666c Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sat, 25 Jan 2025 11:58:20 -0800
Subject: [PATCH 2/2] [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.
---
.../InstCombine/InstCombineSimplifyDemanded.cpp | 9 ++++++---
llvm/test/Transforms/InstCombine/fsh.ll | 3 ++-
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 943598a30f040f..1b89839a72b94b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1039,11 +1039,14 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
if (I->getOperand(0) != I->getOperand(1)) {
- if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown,
- Depth + 1, Q) ||
+ if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1,
+ Q) ||
SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1,
- Q))
+ Q)) {
+ // Range attribute may not longer hold.
+ I->dropPoisonGeneratingReturnAttributes();
return I;
+ }
} else { // fshl is a rotate
// Avoid converting rotate into funnel shift.
// Only simplify if one operand is constant.
diff --git a/llvm/test/Transforms/InstCombine/fsh.ll b/llvm/test/Transforms/InstCombine/fsh.ll
index 34648d586300f0..90c79c564f8555 100644
--- a/llvm/test/Transforms/InstCombine/fsh.ll
+++ b/llvm/test/Transforms/InstCombine/fsh.ll
@@ -1069,11 +1069,12 @@ entry:
ret <2 x i31> %res
}
+;; #124387 Range attribute no longer holds after operands changed.
define i8 @fshl_range_trunc(i1 %x) {
; CHECK-LABEL: @fshl_range_trunc(
; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[X:%.*]] to i32
; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[ZEXT]], 126
-; CHECK-NEXT: [[FSHL:%.*]] = call range(i32 -4, 2) i32 @llvm.fshl.i32(i32 [[OR]], i32 -2, i32 1)
+; CHECK-NEXT: [[FSHL:%.*]] = call i32 @llvm.fshl.i32(i32 [[OR]], i32 -2, i32 1)
; CHECK-NEXT: [[TR:%.*]] = trunc nuw i32 [[FSHL]] to i8
; CHECK-NEXT: ret i8 [[TR]]
;
More information about the llvm-commits
mailing list