mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-01 07:11:45 +00:00
InstCombine: Avoid introducing poison values when lowering llvm.amdgcn.[us]bfe
Summary: When the 3rd argument to these intrinsics is zero, lowering them to shift instructions produces poison values, since we end up with shift amounts equal to the number of bits in the shifted value. This means we can only lower these intrinsics if we can prove that the 3rd argument is not zero. Reviewers: arsenm Reviewed By: arsenm Subscribers: bnieuwenhuizen, jvesely, wdng, nhaehnle, llvm-commits Differential Revision: https://reviews.llvm.org/D53739 llvm-svn: 346422
This commit is contained in:
parent
628412cc49
commit
0de137231d
@ -3479,22 +3479,14 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
|
||||
bool Signed = II->getIntrinsicID() == Intrinsic::amdgcn_sbfe;
|
||||
|
||||
// TODO: Also emit sub if only width is constant.
|
||||
if (!CWidth && COffset && Offset == 0) {
|
||||
Constant *KSize = ConstantInt::get(COffset->getType(), IntSize);
|
||||
Value *ShiftVal = Builder.CreateSub(KSize, II->getArgOperand(2));
|
||||
ShiftVal = Builder.CreateZExt(ShiftVal, II->getType());
|
||||
|
||||
Value *Shl = Builder.CreateShl(Src, ShiftVal);
|
||||
Value *RightShift = Signed ? Builder.CreateAShr(Shl, ShiftVal)
|
||||
: Builder.CreateLShr(Shl, ShiftVal);
|
||||
RightShift->takeName(II);
|
||||
return replaceInstUsesWith(*II, RightShift);
|
||||
}
|
||||
|
||||
if (!CWidth || !COffset)
|
||||
break;
|
||||
|
||||
// The case of Width == 0 is handled above, which makes this tranformation
|
||||
// safe. If Width == 0, then the ashr and lshr instructions become poison
|
||||
// value since the shift amount would be equal to the bit size.
|
||||
assert(Width != 0);
|
||||
|
||||
// TODO: This allows folding to undef when the hardware has specific
|
||||
// behavior?
|
||||
if (Offset + Width < IntSize) {
|
||||
|
@ -934,32 +934,23 @@ define i32 @ubfe_offset_33(i32 %src, i32 %width) {
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @ubfe_offset_0(
|
||||
; CHECK-NEXT: %1 = sub i32 32, %width
|
||||
; CHECK-NEXT: %2 = lshr i32 -1, %1
|
||||
; CHECK-NEXT: %bfe = and i32 %2, %src
|
||||
; CHECK-NEXT: ret i32 %bfe
|
||||
; CHECK-NEXT: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 0, i32 %width)
|
||||
define i32 @ubfe_offset_0(i32 %src, i32 %width) {
|
||||
%bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 0, i32 %width)
|
||||
ret i32 %bfe
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @ubfe_offset_32(
|
||||
; CHECK-NEXT: %1 = sub i32 32, %width
|
||||
; CHECK-NEXT: %2 = lshr i32 -1, %1
|
||||
; CHECK-NEXT: %bfe = and i32 %2, %src
|
||||
; CHECK-NEXT: ret i32 %bfe
|
||||
; CHECK-NEXT: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 0, i32 %width)
|
||||
define i32 @ubfe_offset_32(i32 %src, i32 %width) {
|
||||
%bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 32, i32 %width)
|
||||
ret i32 %bfe
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @ubfe_offset_31(
|
||||
; CHECK-NEXT: %1 = sub i32 32, %width
|
||||
; CHECK-NEXT: %2 = lshr i32 -1, %1
|
||||
; CHECK-NEXT: %bfe = and i32 %2, %src
|
||||
; CHECK-NEXT: ret i32 %bfe
|
||||
; CHECK-NEXT: %bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 31, i32 %width)
|
||||
define i32 @ubfe_offset_31(i32 %src, i32 %width) {
|
||||
%bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 32, i32 %width)
|
||||
%bfe = call i32 @llvm.amdgcn.ubfe.i32(i32 %src, i32 31, i32 %width)
|
||||
ret i32 %bfe
|
||||
}
|
||||
|
||||
@ -1040,11 +1031,7 @@ define i64 @ubfe_offset_33_width_4_i64(i64 %src) {
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @ubfe_offset_0_i64(
|
||||
; CHECK-NEXT: %1 = sub i32 64, %width
|
||||
; CHECK-NEXT: %2 = zext i32 %1 to i64
|
||||
; CHECK-NEXT: %3 = lshr i64 -1, %2
|
||||
; CHECK-NEXT: %bfe = and i64 %3, %src
|
||||
; CHECK-NEXT: ret i64 %bfe
|
||||
; CHECK-NEXT: %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 0, i32 %width)
|
||||
define i64 @ubfe_offset_0_i64(i64 %src, i32 %width) {
|
||||
%bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 0, i32 %width)
|
||||
ret i64 %bfe
|
||||
@ -1066,12 +1053,9 @@ declare i32 @llvm.amdgcn.sbfe.i32(i32, i32, i32) nounwind readnone
|
||||
declare i64 @llvm.amdgcn.sbfe.i64(i64, i32, i32) nounwind readnone
|
||||
|
||||
; CHECK-LABEL: @sbfe_offset_31(
|
||||
; CHECK-NEXT: %1 = sub i32 32, %width
|
||||
; CHECK-NEXT: %2 = shl i32 %src, %1
|
||||
; CHECK-NEXT: %bfe = ashr i32 %2, %1
|
||||
; CHECK-NEXT: ret i32 %bfe
|
||||
; CHECK-NEXT: %bfe = call i32 @llvm.amdgcn.sbfe.i32(i32 %src, i32 31, i32 %width)
|
||||
define i32 @sbfe_offset_31(i32 %src, i32 %width) {
|
||||
%bfe = call i32 @llvm.amdgcn.sbfe.i32(i32 %src, i32 32, i32 %width)
|
||||
%bfe = call i32 @llvm.amdgcn.sbfe.i32(i32 %src, i32 31, i32 %width)
|
||||
ret i32 %bfe
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user