[cfe-dev] NSW and ExtLdPromotion()
Lawrence
lawrence at codeaurora.org
Mon Aug 10 18:53:56 PDT 2015
Hi, All:
I have a testcase which produced incorrect result, it's caused by the
combination of nsw flag and ExtLdPromotion, I am leaning to say Clang set
nsw flag incorrectly, but please let me know if I was wrong.
Here is the reduced testcase:
long long foo(int *a)
{
long long c;
c = *a * 1405;
return c;
}
Clang emitted the following IR (It is done by EmitMUL() in CGExprScalar.cpp,
while
CGF.getLangOpts().getSignedOverflowBehavior()=LangOptions::SOB_Undefined and
CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)=false):
; Function Attrs: nounwind readonly
define i64 @foo(i32* nocapture readonly %a) #0 {
entry:
%0 = load i32* %a, align 4, !tbaa !1
%mul = mul nsw i32 %0, 1405
%conv = sext i32 %mul to i64
ret i64 %conv
}
Question 1: Is it reasonable to say "mul" is "No Signed Wrap" ? *a *1405
could overflow though.
Question 2: Why SignedOverflowBehavior is set to LangOptions::SOB_Undefined
by default?
Question 3: What about CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)
Because of nsw, and with Quentin patch (git-svn-id:
https://llvm.org/svn/llvm-project/llvm/trunk@233753
91177308-0d34-0410-b5e6-96231b3b80d8), ExtLdPromotion() in
CodeGenPrepare.cpp is able promote the sext to the following:
define i64 @foo(i32* nocapture readonly %a) #0 {
entry:
%0 = load i32* %a, align 4, !tbaa !1
%conv = sext i32 %0 to i64
%mul = mul nsw i64 %conv, 1405
ret i64 %mul
}
This promotion itself looks fine to me if nsw is true, and the final code
becomes:
ldrsw x8, [x0]
movz w9, #0x57d
mul x0, x8, x9
ret
The results is different from a 32-bit mul then sext, at least for my
testcase.
Without nsw, ExtLdPromotion() didn't change anything, and the result is
correct.
Any thoughts would be helpful.
Regards
Lawrence Hu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150810/219aa61c/attachment.html>
More information about the cfe-dev
mailing list