Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
llvm.7809
backport-llvm-r197234
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File backport-llvm-r197234 of Package llvm.7809
------------------------------------------------------------------------ r197234 | rsandifo | 2013-12-13 16:07:39 +0100 (Fri, 13 Dec 2013) | 10 lines [SystemZ] Make more use of LTGFR InstCombine turns (sext (trunc)) into (ashr (shl)), then converts any comparison of the ashr against zero into a comparison of the shl against zero. This makes sense in itself, but we want to undo it for z, since the sign- extension instruction has a CC-setting form. I've included tests for both the original and InstCombined variants, but the former already worked. The patch fixes the latter. ------------------------------------------------------------------------ Index: test/CodeGen/SystemZ/int-cmp-44.ll =================================================================== --- test/CodeGen/SystemZ/int-cmp-44.ll.orig +++ test/CodeGen/SystemZ/int-cmp-44.ll @@ -797,3 +797,51 @@ store: exit: ret i32 %val } + +; Test f35 for in-register extensions. +define i64 @f39(i64 %dummy, i64 %a, i64 *%dest) { +; CHECK-LABEL: f39: +; CHECK: ltgfr %r2, %r3 +; CHECK-NEXT: #APP +; CHECK-NEXT: blah %r2 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: jh .L{{.*}} +; CHECK: br %r14 +entry: + %val = trunc i64 %a to i32 + %ext = sext i32 %val to i64 + call void asm sideeffect "blah $0", "{r2}"(i64 %ext) + %cmp = icmp sgt i64 %ext, 0 + br i1 %cmp, label %exit, label %store + +store: + store i64 %ext, i64 *%dest + br label %exit + +exit: + ret i64 %ext +} + +; ...and again with what InstCombine would produce for f40. +define i64 @f40(i64 %dummy, i64 %a, i64 *%dest) { +; CHECK-LABEL: f40: +; CHECK: ltgfr %r2, %r3 +; CHECK-NEXT: #APP +; CHECK-NEXT: blah %r2 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: jh .L{{.*}} +; CHECK: br %r14 +entry: + %shl = shl i64 %a, 32 + %ext = ashr i64 %shl, 32 + call void asm sideeffect "blah $0", "{r2}"(i64 %ext) + %cmp = icmp sgt i64 %shl, 0 + br i1 %cmp, label %exit, label %store + +store: + store i64 %ext, i64 *%dest + br label %exit + +exit: + ret i64 %ext +} Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp.orig +++ lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1280,6 +1280,36 @@ static void adjustForFNeg(SDValue &CmpOp } } +// Check whether CmpOp0 is (shl X, 32), CmpOp1 is 0, and whether X is +// also sign-extended. In that case it is better to test the result +// of the sign extension using LTGFR. +// +// This case is important because InstCombine transforms a comparison +// with (sext (trunc X)) into a comparison with (shl X, 32). +static void adjustForLTGFR(SDValue &CmpOp0, SDValue &CmpOp1, + unsigned &IcmpType) { + // Check for a comparison between (shl X, 32) and 0. + if (CmpOp0.getOpcode() == ISD::SHL && + CmpOp0.getValueType() == MVT::i64 && + CmpOp1.getOpcode() == ISD::Constant && + cast<ConstantSDNode>(CmpOp1)->getZExtValue() == 0) { + ConstantSDNode *C1 = dyn_cast<ConstantSDNode>(CmpOp0.getOperand(1)); + if (C1 && C1->getZExtValue() == 32) { + SDValue ShlOp0 = CmpOp0.getOperand(0); + // See whether X has any SIGN_EXTEND_INREG uses. + for (SDNode::use_iterator I = ShlOp0->use_begin(), E = ShlOp0->use_end(); + I != E; ++I) { + SDNode *N = *I; + if (N->getOpcode() == ISD::SIGN_EXTEND_INREG && + cast<VTSDNode>(N->getOperand(1))->getVT() == MVT::i32) { + CmpOp0 = SDValue(N, 0); + return; + } + } + } + } +} + // Return true if shift operation N has an in-range constant shift value. // Store it in ShiftVal if so. static bool isSimpleShift(SDValue N, unsigned &ShiftVal) { @@ -1497,6 +1527,7 @@ static SDValue emitCmp(const SystemZTarg adjustForTestUnderMask(DAG, Opcode, CmpOp0, CmpOp1, CCValid, CCMask, ICmpType); adjustForFNeg(CmpOp0, CmpOp1, CCMask); + adjustForLTGFR(CmpOp0, CmpOp1, ICmpType); if (Opcode == SystemZISD::ICMP || Opcode == SystemZISD::TM) return DAG.getNode(Opcode, DL, MVT::Glue, CmpOp0, CmpOp1, DAG.getConstant(ICmpType, MVT::i32));
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor