-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Description
| Bugzilla Link | 11449 |
| Resolution | FIXED |
| Resolved on | Apr 30, 2015 16:13 |
| Version | trunk |
| OS | Linux |
| CC | @efriedma-quic,@sunfishcode,@MatzeB,@nlewycky |
Extended Description
When instcombine sees an add/sub with nsw/nuw, where the sign bit is not demanded, it does not demand the sign bit in the input. The following IR is misoptimized:
; ModuleID = ''
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define i32 @_Z1fiii(i32 %a, i32 %b, i32 %c) nounwind {
entry:
%or = or i32 %b, 2147483647
%xor = xor i32 %a, %or
%add = add nsw i32 %xor, %c
%and = and i32 %add, 2147483647
ret i32 %and
}
define i32 @_Z1gi(i32 %c) nounwind {
entry:
%call = call i32 @_Z1fiii(i32 -1, i32 -1, i32 %c)
ret i32 %call
}
If we run this through opt -inline -instcombine, we get correct IR:
define i32 @_Z1gi(i32 %c) nounwind {
entry:
%and.i = and i32 %c, 2147483647
ret i32 %and.i
}
If we run this through opt -instcombine -inline, we get incorrect IR:
define i32 @_Z1gi(i32 %c) nounwind {
entry:
%add.i = add nsw i32 -2147483648, %c
%and.i = and i32 %add.i, 2147483647
ret i32 %and.i
}
This function produces a trap value for negative %c; the original code did not. Perhaps operators with nsw or nuw should implicitly demand the sign bit from their operands, even if the sign bit of the result is not demanded.