Skip to content

Commit ad50676

Browse files
authored
[InstCombine] Only fold bitcast(fptrunc) if destination type matches fptrunc result type. (llvm#77046)
It's not enough to just make sure destination type is floating point, because the following chain may be incorrectly optimized: ```LLVM %trunc = fptrunc float %src to bfloat %cast = bitcast bfloat %trunc to half ``` Before the fix, the instruction sequence mentioned above used to be translated into single fptrunc instruction as follows: ```LLVM %trunc = fptrunc float %src to half ``` Such transformation was semantically incorrect.
1 parent 142f270 commit ad50676

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

llvm/lib/IR/Instructions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,8 +3203,8 @@ unsigned CastInst::isEliminableCastPair(
32033203
return 0;
32043204
case 4:
32053205
// No-op cast in second op implies firstOp as long as the DestTy
3206-
// is floating point.
3207-
if (DstTy->isFloatingPointTy())
3206+
// matches MidTy.
3207+
if (DstTy == MidTy)
32083208
return firstOp;
32093209
return 0;
32103210
case 5:

llvm/test/Transforms/InstCombine/fptrunc.ll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,16 @@ define half @ItoFtoF_u25_f32_f16(i25 %i) {
190190
%r = fptrunc float %x to half
191191
ret half %r
192192
}
193+
194+
; Negative test - bitcast bfloat to half is not optimized
195+
196+
define half @fptrunc_to_bfloat_bitcast_to_half(float %src) {
197+
; CHECK-LABEL: @fptrunc_to_bfloat_bitcast_to_half(
198+
; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc float [[SRC:%.*]] to bfloat
199+
; CHECK-NEXT: [[CAST:%.*]] = bitcast bfloat [[TRUNC]] to half
200+
; CHECK-NEXT: ret half [[CAST]]
201+
;
202+
%trunc = fptrunc float %src to bfloat
203+
%cast = bitcast bfloat %trunc to half
204+
ret half %cast
205+
}

0 commit comments

Comments
 (0)