From duraid at octopus.com.au Mon Apr 4 00:06:02 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Mon, 4 Apr 2005 00:06:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200504040506.AAA17067@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.10 -> 1.11 --- Log message: fix SREM/UREM, which gave incorrect results for x%y if x was zero. This is an ugly hack, but it seems to work. I should fix this properly and add a test as well. fixes multisource/obsequi (maybe others) --- Diffs of the changes: (+13 -1) IA64ISelPattern.cpp | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletion(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.10 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.11 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.10 Sat Apr 2 04:33:53 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Mon Apr 4 00:05:52 2005 @@ -1087,9 +1087,19 @@ .addReg(TmpF8).addReg(TmpF10).addReg(TmpF10).addReg(TmpPR); BuildMI(BB, IA64::CFNMAS1, 4,TmpF13) .addReg(TmpF4).addReg(TmpF11).addReg(TmpF3).addReg(TmpPR); + + // FIXME: this is unfortunate :( + // the story is that the dest reg of the fnma above and the fma below + // (and therefore possibly the src of the fcvt.fx[u] as well) cannot + // be the same register, or this code breaks if the first argument is + // zero. (e.g. without this hack, 0%8 yields -64, not 0.) BuildMI(BB, IA64::CFMAS1, 4,TmpF14) .addReg(TmpF13).addReg(TmpF12).addReg(TmpF11).addReg(TmpPR); + if(isModulus) { // XXX: fragile! fixes _only_ mod, *breaks* div! ! + BuildMI(BB, IA64::IUSE, 1).addReg(TmpF13); // hack :( + } + if(!isFP) { // round to an integer if(isSigned) @@ -1113,14 +1123,16 @@ BuildMI(BB, IA64::CFMOV, 2, Result) .addReg(bogoResult).addReg(TmpF15).addReg(TmpPR); } - else + else { BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TmpF15); + } } else { // this is a modulus if(!isFP) { // answer = q * (-b) + a unsigned ModulusResult = MakeReg(MVT::f64); unsigned TmpF = MakeReg(MVT::f64); unsigned TmpI = MakeReg(MVT::i64); + BuildMI(BB, IA64::SUB, 2, TmpI).addReg(IA64::r0).addReg(Tmp2); BuildMI(BB, IA64::SETFSIG, 1, TmpF).addReg(TmpI); BuildMI(BB, IA64::XMAL, 3, ModulusResult) From natebegeman at mac.com Mon Apr 4 01:52:49 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 4 Apr 2005 01:52:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504040652.BAA17385@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.39 -> 1.40 --- Log message: Fix i64 return, fix CopyFromReg --- Diffs of the changes: (+14 -3) PPC32ISelPattern.cpp | 17 ++++++++++++++--- 1 files changed, 14 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.39 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.40 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.39 Sun Apr 3 18:11:17 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Mon Apr 4 01:52:38 2005 @@ -172,8 +172,13 @@ // We need to load the argument to a virtual register if we determined above // that we ran out of physical registers of the appropriate type if (needsLoad) { + unsigned SubregOffset = 0; + if (ObjectVT == MVT::i8) SubregOffset = 3; + if (ObjectVT == MVT::i16) SubregOffset = 2; int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, + DAG.getConstant(SubregOffset, MVT::i32)); argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN); } @@ -933,6 +938,9 @@ break; } + if (ISD::CopyFromReg == opcode) + DestType = N.getValue(0).getValueType(); + if (DestType == MVT::f64 || DestType == MVT::f32) if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode && ISD::UNDEF != opcode) return SelectExprFP(N, Result); @@ -1109,9 +1117,12 @@ case MVT::i8: case MVT::i16: case MVT::i32: - BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3).addReg(PPC::R3); - if (Node->getValueType(1) == MVT::i32) - BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R4).addReg(PPC::R4); + if (Node->getValueType(1) == MVT::i32) { + BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R3).addReg(PPC::R3); + BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R4).addReg(PPC::R4); + } else { + BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3).addReg(PPC::R3); + } break; case MVT::f32: case MVT::f64: From natebegeman at mac.com Mon Apr 4 04:09:12 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 4 Apr 2005 04:09:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504040909.EAA11720@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.40 -> 1.41 --- Log message: i1 loads should also be from the low byte of the argument word. --- Diffs of the changes: (+1 -1) PPC32ISelPattern.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.40 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.41 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.40 Mon Apr 4 01:52:38 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Mon Apr 4 04:09:00 2005 @@ -173,7 +173,7 @@ // that we ran out of physical registers of the appropriate type if (needsLoad) { unsigned SubregOffset = 0; - if (ObjectVT == MVT::i8) SubregOffset = 3; + if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3; if (ObjectVT == MVT::i16) SubregOffset = 2; int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); From lattner at cs.uiuc.edu Mon Apr 4 11:06:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 4 Apr 2005 11:06:49 -0500 Subject: [llvm-commits] CVS: llvm-test/TEST.dsprecision.report Message-ID: <200504041606.j34G6nIO020002@apoc.cs.uiuc.edu> Changes in directory llvm-test: TEST.dsprecision.report updated: 1.4 -> 1.5 --- Log message: add anders to this report --- Diffs of the changes: (+10 -5) TEST.dsprecision.report | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) Index: llvm-test/TEST.dsprecision.report diff -u llvm-test/TEST.dsprecision.report:1.4 llvm-test/TEST.dsprecision.report:1.5 --- llvm-test/TEST.dsprecision.report:1.4 Sat Mar 26 18:54:03 2005 +++ llvm-test/TEST.dsprecision.report Mon Apr 4 11:06:32 2005 @@ -86,30 +86,35 @@ ["basic", 'BASIC MA:.* \((.*)\)'], ["steens-fi", 'STEENS-FI MA:.* \((.*)\)'], ["steens-fs", 'STEENS-FS MA:.* \((.*)\)'], - ["ds", 'DS MA:.* \((.*)\)'], + ["anders", 'ANDERS MA:.* \((.*)\)'], + ["ds-aa", 'DS MA:.* \((.*)\)'], [], # Mod&Ref percents ["basic", 'BASIC MR:.* \((.*)\)'], ["steens-fi", 'STEENS-FI MR:.* \((.*)\)'], ["steens-fs", 'STEENS-FS MR:.* \((.*)\)'], - ["ds", 'DS MR:.* \((.*)\)'], + ["anders", 'ANDERS MR:.* \((.*)\)'], + ["ds-aa", 'DS MR:.* \((.*)\)'], [], # Mod Percents ["basic", 'BASIC JUSTMOD:.* \((.*)\)'], ["steens-fi", 'STEENS-FI JUSTMOD:.* \((.*)\)'], ["steens-fs", 'STEENS-FS JUSTMOD:.* \((.*)\)'], - ["ds", 'DS JUSTMOD:.* \((.*)\)'], + ["anders", 'ANDERS JUSTMOD:.* \((.*)\)'], + ["ds-aa", 'DS JUSTMOD:.* \((.*)\)'], [], # Ref Percents ["basic", 'BASIC JUSTREF:.* \((.*)\)'], ["steens-fi", 'STEENS-FI JUSTREF:.* \((.*)\)'], ["steens-fs", 'STEENS-FS JUSTREF:.* \((.*)\)'], - ["ds", 'DS JUSTREF:.* \((.*)\)'], + ["anders", 'ANDERS JUSTREF:.* \((.*)\)'], + ["ds-aa", 'DS JUSTREF:.* \((.*)\)'], [], # No Mod/Ref Percents ["basic", 'BASIC NOMR:.* \((.*)\)'], ["steens-fi", 'STEENS-FI NOMR:.* \((.*)\)'], ["steens-fs", 'STEENS-FS NOMR:.* \((.*)\)'], - ["ds", 'DS NOMR:.* \((.*)\)'], + ["anders", 'ANDERS NOMR:.* \((.*)\)'], + ["ds-aa", 'DS NOMR:.* \((.*)\)'], [], ); From lattner at cs.uiuc.edu Mon Apr 4 11:07:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 4 Apr 2005 11:07:03 -0500 Subject: [llvm-commits] CVS: llvm-test/TEST.dsprecision.Makefile Message-ID: <200504041607.j34G73aa020014@apoc.cs.uiuc.edu> Changes in directory llvm-test: TEST.dsprecision.Makefile updated: 1.2 -> 1.3 --- Log message: add anders and newlines to this report --- Diffs of the changes: (+38 -0) TEST.dsprecision.Makefile | 38 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 38 insertions(+) Index: llvm-test/TEST.dsprecision.Makefile diff -u llvm-test/TEST.dsprecision.Makefile:1.2 llvm-test/TEST.dsprecision.Makefile:1.3 --- llvm-test/TEST.dsprecision.Makefile:1.2 Sat Mar 26 15:49:49 2005 +++ llvm-test/TEST.dsprecision.Makefile Mon Apr 4 11:06:50 2005 @@ -16,50 +16,88 @@ -($(LOPT) -basicaa -aa-eval -disable-output $<) > Output/$*.basicaa.out 2>&1 @echo -n "BASIC MA: " >> $@ - at grep 'may alias responses' Output/$*.basicaa.out >> $@ + @echo >> $@ @echo -n "BASIC NOMR: " >> $@ - at grep 'no mod/ref responses' Output/$*.basicaa.out >> $@ + @echo >> $@ @echo -n "BASIC JUSTREF: " >> $@ - at grep '[0-9] ref responses' Output/$*.basicaa.out >> $@ + @echo >> $@ @echo -n "BASIC JUSTMOD: " >> $@ - at grep 'mod responses' Output/$*.basicaa.out >> $@ + @echo >> $@ @echo -n "BASIC MR: " >> $@ - at grep 'mod & ref responses' Output/$*.basicaa.out >> $@ + @echo >> $@ @ -($(LOPT) -steens-aa -disable-ds-field-sensitivity -aa-eval \ -disable-output $<) > Output/$*.steensfiaa.out 2>&1 @echo -n "STEENS-FI MA: " >> $@ - at grep 'may alias responses' Output/$*.steensfiaa.out >> $@ + @echo >> $@ @echo -n "STEENS-FI NOMR: " >> $@ - at grep 'no mod/ref responses' Output/$*.steensfiaa.out >> $@ + @echo >> $@ @echo -n "STEENS-FI JUSTREF: " >> $@ - at grep '[0-9] ref responses' Output/$*.steensfiaa.out >> $@ + @echo >> $@ @echo -n "STEENS-FI JUSTMOD: " >> $@ - at grep 'mod responses' Output/$*.steensfiaa.out >> $@ + @echo >> $@ @echo -n "STEENS-FI MR: " >> $@ - at grep 'mod & ref responses' Output/$*.steensfiaa.out >> $@ + @echo >> $@ @ -($(LOPT) -steens-aa -aa-eval -disable-output $<) > Output/$*.steensfsaa.out 2>&1 @echo -n "STEENS-FS MA: " >> $@ - at grep 'may alias responses' Output/$*.steensfsaa.out >> $@ + @echo >> $@ @echo -n "STEENS-FS NOMR: " >> $@ - at grep 'no mod/ref responses' Output/$*.steensfsaa.out >> $@ + @echo >> $@ @echo -n "STEENS-FS JUSTREF: " >> $@ - at grep '[0-9] ref responses' Output/$*.steensfsaa.out >> $@ + @echo >> $@ @echo -n "STEENS-FS JUSTMOD: " >> $@ - at grep 'mod responses' Output/$*.steensfsaa.out >> $@ + @echo >> $@ @echo -n "STEENS-FS MR: " >> $@ - at grep 'mod & ref responses' Output/$*.steensfsaa.out >> $@ + @echo >> $@ + @ + -($(LOPT) -anders-aa -aa-eval -disable-output $<) > Output/$*.andersaa.out 2>&1 + @echo -n "ANDERS MA: " >> $@ + - at grep 'may alias responses' Output/$*.andersaa.out >> $@ + @echo >> $@ + @echo -n "ANDERS NOMR: " >> $@ + - at grep 'no mod/ref responses' Output/$*.andersaa.out >> $@ + @echo >> $@ + @echo -n "ANDERS JUSTREF: " >> $@ + - at grep '[0-9] ref responses' Output/$*.andersaa.out >> $@ + @echo >> $@ + @echo -n "ANDERS JUSTMOD: " >> $@ + - at grep 'mod responses' Output/$*.andersaa.out >> $@ + @echo >> $@ + @echo -n "ANDERS MR: " >> $@ + - at grep 'mod & ref responses' Output/$*.andersaa.out >> $@ + @echo >> $@ + @ -($(LOPT) -ds-aa -aa-eval -disable-output $<) > Output/$*.dsaa.out 2>&1 @echo -n "DS MA: " >> $@ - at grep 'may alias responses' Output/$*.dsaa.out >> $@ + @echo >> $@ @echo -n "DS NOMR: " >> $@ - at grep 'no mod/ref responses' Output/$*.dsaa.out >> $@ + @echo >> $@ @echo -n "DS JUSTREF: " >> $@ - at grep '[0-9] ref responses' Output/$*.dsaa.out >> $@ + @echo >> $@ @echo -n "DS JUSTMOD: " >> $@ - at grep 'mod responses' Output/$*.dsaa.out >> $@ + @echo >> $@ @echo -n "DS MR: " >> $@ - at grep 'mod & ref responses' Output/$*.dsaa.out >> $@ + @echo >> $@ $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt From alenhar2 at cs.uiuc.edu Mon Apr 4 14:56:20 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 4 Apr 2005 14:56:20 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/254.gap/Makefile Message-ID: <200504041956.j34JuKwG031705@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/254.gap: Makefile updated: 1.7 -> 1.8 --- Log message: Added Alpha Compatibility flag --- Diffs of the changes: (+3 -0) Makefile | 3 +++ 1 files changed, 3 insertions(+) Index: llvm-test/External/SPEC/CINT2000/254.gap/Makefile diff -u llvm-test/External/SPEC/CINT2000/254.gap/Makefile:1.7 llvm-test/External/SPEC/CINT2000/254.gap/Makefile:1.8 --- llvm-test/External/SPEC/CINT2000/254.gap/Makefile:1.7 Tue Mar 8 16:43:50 2005 +++ llvm-test/External/SPEC/CINT2000/254.gap/Makefile Mon Apr 4 14:56:02 2005 @@ -10,6 +10,9 @@ ifeq ($(ARCH),Sparc) CPPFLAGS+= -DSPEC_CPU2000_LP64 endif +ifeq ($(ARCH),Alpha) +CPPFLAGS+= -DSPEC_CPU2000_LP64 +endif ifeq ($(OS),Darwin) CPPFLAGS += -DSYS_IS_BSD From alenhar2 at cs.uiuc.edu Mon Apr 4 14:57:10 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 4 Apr 2005 14:57:10 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/255.vortex/Makefile Message-ID: <200504041957.j34JvAZG031738@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/255.vortex: Makefile updated: 1.8 -> 1.9 --- Log message: Added Alpha Compatibility flag --- Diffs of the changes: (+5 -0) Makefile | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm-test/External/SPEC/CINT2000/255.vortex/Makefile diff -u llvm-test/External/SPEC/CINT2000/255.vortex/Makefile:1.8 llvm-test/External/SPEC/CINT2000/255.vortex/Makefile:1.9 --- llvm-test/External/SPEC/CINT2000/255.vortex/Makefile:1.8 Mon Sep 6 23:18:02 2004 +++ llvm-test/External/SPEC/CINT2000/255.vortex/Makefile Mon Apr 4 14:56:57 2005 @@ -15,3 +15,8 @@ CPPFLAGS += -DSPEC_CPU2000_LP64 endif +ifeq ($(ARCH),Alpha) + ## SPEC portability note for vortex says to use this flag on 64-bit machines + CPPFLAGS += -DSPEC_CPU2000_LP64 +endif + From alenhar2 at cs.uiuc.edu Mon Apr 4 14:58:37 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 4 Apr 2005 14:58:37 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/255.vortex/Makefile Message-ID: <200504041958.j34JwbHl031791@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/255.vortex: Makefile updated: 1.9 -> 1.10 --- Log message: Added Alpha (and IA64, because I'm nice like that) compatibility flag --- Diffs of the changes: (+6 -0) Makefile | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm-test/External/SPEC/CINT2000/255.vortex/Makefile diff -u llvm-test/External/SPEC/CINT2000/255.vortex/Makefile:1.9 llvm-test/External/SPEC/CINT2000/255.vortex/Makefile:1.10 --- llvm-test/External/SPEC/CINT2000/255.vortex/Makefile:1.9 Mon Apr 4 14:56:57 2005 +++ llvm-test/External/SPEC/CINT2000/255.vortex/Makefile Mon Apr 4 14:58:24 2005 @@ -20,3 +20,9 @@ CPPFLAGS += -DSPEC_CPU2000_LP64 endif +ifeq ($(ARCH),IA64) + ## SPEC portability note for vortex says to use this flag on 64-bit machines + CPPFLAGS += -DSPEC_CPU2000_LP64 +endif + + From alenhar2 at cs.uiuc.edu Mon Apr 4 14:59:16 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 4 Apr 2005 14:59:16 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/254.gap/Makefile Message-ID: <200504041959.j34JxGXA031812@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/254.gap: Makefile updated: 1.8 -> 1.9 --- Log message: Added Alpha (and IA64, because I'm nice like that) compatibility flag --- Diffs of the changes: (+3 -0) Makefile | 3 +++ 1 files changed, 3 insertions(+) Index: llvm-test/External/SPEC/CINT2000/254.gap/Makefile diff -u llvm-test/External/SPEC/CINT2000/254.gap/Makefile:1.8 llvm-test/External/SPEC/CINT2000/254.gap/Makefile:1.9 --- llvm-test/External/SPEC/CINT2000/254.gap/Makefile:1.8 Mon Apr 4 14:56:02 2005 +++ llvm-test/External/SPEC/CINT2000/254.gap/Makefile Mon Apr 4 14:59:02 2005 @@ -13,6 +13,9 @@ ifeq ($(ARCH),Alpha) CPPFLAGS+= -DSPEC_CPU2000_LP64 endif +ifeq ($(ARCH),IA64) +CPPFLAGS+= -DSPEC_CPU2000_LP64 +endif ifeq ($(OS),Darwin) CPPFLAGS += -DSYS_IS_BSD From alenhar2 at cs.uiuc.edu Mon Apr 4 15:00:06 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 4 Apr 2005 15:00:06 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/176.gcc/Makefile Message-ID: <200504042000.j34K06c0031847@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/176.gcc: Makefile updated: 1.11 -> 1.12 --- Log message: Added Alpha (and IA64, because I'm nice like that) compatibility flag --- Diffs of the changes: (+10 -0) Makefile | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm-test/External/SPEC/CINT2000/176.gcc/Makefile diff -u llvm-test/External/SPEC/CINT2000/176.gcc/Makefile:1.11 llvm-test/External/SPEC/CINT2000/176.gcc/Makefile:1.12 --- llvm-test/External/SPEC/CINT2000/176.gcc/Makefile:1.11 Mon Sep 6 23:18:02 2004 +++ llvm-test/External/SPEC/CINT2000/176.gcc/Makefile Mon Apr 4 14:59:52 2005 @@ -18,3 +18,13 @@ ## SPEC portability note for GCC says to use these flags and cross fingers: CPPFLAGS += -DSPEC_CPU2000_LP64 endif +ifeq ($(ARCH),Alpha) + ## SPEC portability note for GCC says to use these flags and cross fingers: + CPPFLAGS += -DSPEC_CPU2000_LP64 +endif +ifeq ($(ARCH),IA64) + ## SPEC portability note for GCC says to use these flags and cross fingers: + CPPFLAGS += -DSPEC_CPU2000_LP64 +endif + + From alenhar2 at cs.uiuc.edu Mon Apr 4 15:01:43 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 4 Apr 2005 15:01:43 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/253.perlbmk/Makefile Message-ID: <200504042001.j34K1h8a031872@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/253.perlbmk: Makefile updated: 1.10 -> 1.11 --- Log message: Added Alpha compatibility flag --- Diffs of the changes: (+4 -0) Makefile | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm-test/External/SPEC/CINT2000/253.perlbmk/Makefile diff -u llvm-test/External/SPEC/CINT2000/253.perlbmk/Makefile:1.10 llvm-test/External/SPEC/CINT2000/253.perlbmk/Makefile:1.11 --- llvm-test/External/SPEC/CINT2000/253.perlbmk/Makefile:1.10 Mon Sep 6 23:18:02 2004 +++ llvm-test/External/SPEC/CINT2000/253.perlbmk/Makefile Mon Apr 4 15:01:29 2005 @@ -2,6 +2,10 @@ REQUIRES_EH_SUPPORT = 1 CPPFLAGS = -DSPEC_CPU2000_LINUX -Dbool=char -DI_TIME -DI_SYS_TIME +ifeq ($(ARCH),Alpha) + CPPFLAGS += -DSPEC_CPU2000_LINUX_ALPHA +endif + ifeq ($(RUN_TYPE),test) RUN_OPTIONS = test.pl STDOUT_FILENAME := test.out From alenhar2 at cs.uiuc.edu Mon Apr 4 15:04:14 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 4 Apr 2005 15:04:14 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/186.crafty/Makefile Message-ID: <200504042004.j34K4ErY031893@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/186.crafty: Makefile updated: 1.8 -> 1.9 --- Log message: Added Alpha compatibility flag --- Diffs of the changes: (+6 -0) Makefile | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm-test/External/SPEC/CINT2000/186.crafty/Makefile diff -u llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.8 llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.9 --- llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.8 Tue Sep 14 20:14:09 2004 +++ llvm-test/External/SPEC/CINT2000/186.crafty/Makefile Mon Apr 4 15:04:00 2005 @@ -2,7 +2,13 @@ #RUN_OPTIONS = STDIN_FILENAME = crafty.in STDOUT_FILENAME = crafty.out + +ifeq ($(ARCH),Alpha) CPPFLAGS = -DSPEC_CPU2000 -DLINUX_i386 +else +CPPFLAGS = -DSPEC_CPU2000 -DALPHA -DLINUX +endif + Source = $(addprefix $(SPEC_BENCH_DIR)/src/, \ attacks.c draw.c enprise.c init.c iterate.c make.c nexte.c output.c \ preeval.c resign.c searchr.c swap.c utility.c boolean.c drawn.c \ From alenhar2 at cs.uiuc.edu Mon Apr 4 15:07:24 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 4 Apr 2005 15:07:24 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT95/147.vortex/Makefile Message-ID: <200504042007.j34K7O26031925@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT95/147.vortex: Makefile updated: 1.4 -> 1.5 --- Log message: Added Alpha (and IA64, because I'm nice like that) compatibility flag --- Diffs of the changes: (+8 -0) Makefile | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm-test/External/SPEC/CINT95/147.vortex/Makefile diff -u llvm-test/External/SPEC/CINT95/147.vortex/Makefile:1.4 llvm-test/External/SPEC/CINT95/147.vortex/Makefile:1.5 --- llvm-test/External/SPEC/CINT95/147.vortex/Makefile:1.4 Mon Sep 6 23:18:02 2004 +++ llvm-test/External/SPEC/CINT95/147.vortex/Makefile Mon Apr 4 15:07:11 2005 @@ -10,6 +10,14 @@ ## SPEC portability note for vortex says to use this flag on 64-bit machines CPPFLAGS += -DSPEC_CPU2000_LP64 endif +ifeq ($(ARCH),Alpha) + ## SPEC portability note for vortex says to use this flag on 64-bit machines + CPPFLAGS += -DSPEC_CPU2000_LP64 +endif +ifeq ($(ARCH),IA64) + ## SPEC portability note for vortex says to use this flag on 64-bit machines + CPPFLAGS += -DSPEC_CPU2000_LP64 +endif ifeq ($(ENDIAN), big) RUN_OPTIONS = vortex.in.big From lattner at cs.uiuc.edu Mon Apr 4 16:35:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 4 Apr 2005 16:35:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200504042135.j34LZof2032630@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.35 -> 1.36 --- Log message: Make sure to notice that explicit physregs are used in the function --- Diffs of the changes: (+29 -23) VirtRegMap.cpp | 52 +++++++++++++++++++++++++++++----------------------- 1 files changed, 29 insertions(+), 23 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.35 llvm/lib/CodeGen/VirtRegMap.cpp:1.36 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.35 Sun Jan 23 16:45:13 2005 +++ llvm/lib/CodeGen/VirtRegMap.cpp Mon Apr 4 16:35:34 2005 @@ -157,31 +157,34 @@ MachineInstr &MI = *MII; for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); - if (MO.isRegister() && MO.getReg() && - MRegisterInfo::isVirtualRegister(MO.getReg())) { - unsigned VirtReg = MO.getReg(); - unsigned PhysReg = VRM.getPhys(VirtReg); - if (VRM.hasStackSlot(VirtReg)) { - int StackSlot = VRM.getStackSlot(VirtReg); - - if (MO.isUse() && - std::find(LoadedRegs.begin(), LoadedRegs.end(), VirtReg) - == LoadedRegs.end()) { - MRI.loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot); - LoadedRegs.push_back(VirtReg); - ++NumLoads; - DEBUG(std::cerr << '\t' << *prior(MII)); - } - - if (MO.isDef()) { - MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot); - ++NumStores; + if (MO.isRegister() && MO.getReg()) + if (MRegisterInfo::isVirtualRegister(MO.getReg())) { + unsigned VirtReg = MO.getReg(); + unsigned PhysReg = VRM.getPhys(VirtReg); + if (VRM.hasStackSlot(VirtReg)) { + int StackSlot = VRM.getStackSlot(VirtReg); + + if (MO.isUse() && + std::find(LoadedRegs.begin(), LoadedRegs.end(), VirtReg) + == LoadedRegs.end()) { + MRI.loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot); + LoadedRegs.push_back(VirtReg); + ++NumLoads; + DEBUG(std::cerr << '\t' << *prior(MII)); + } + + if (MO.isDef()) { + MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot); + ++NumStores; + } } + PhysRegsUsed[PhysReg] = true; + MI.SetMachineOperandReg(i, PhysReg); + } else { + PhysRegsUsed[MO.getReg()] = true; } - PhysRegsUsed[PhysReg] = true; - MI.SetMachineOperandReg(i, PhysReg); - } } + DEBUG(std::cerr << '\t' << MI); LoadedRegs.clear(); } @@ -312,7 +315,10 @@ for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); if (MO.isRegister() && MO.getReg() && - MRegisterInfo::isVirtualRegister(MO.getReg())) { + MRegisterInfo::isPhysicalRegister(MO.getReg())) + PhysRegsUsed[MO.getReg()] = true; + else if (MO.isRegister() && MO.getReg() && + MRegisterInfo::isVirtualRegister(MO.getReg())) { unsigned VirtReg = MO.getReg(); if (!VRM.hasStackSlot(VirtReg)) { From natebegeman at mac.com Mon Apr 4 16:48:24 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 4 Apr 2005 16:48:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Message-ID: <200504042148.QAA14997@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32RegisterInfo.cpp updated: 1.7 -> 1.8 --- Log message: Remove unnecessary register copy now that regalloc is fixed --- Diffs of the changes: (+0 -2) PPC32RegisterInfo.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.7 llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.8 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.7 Tue Oct 26 00:40:45 2004 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Mon Apr 4 16:48:13 2005 @@ -286,8 +286,6 @@ if (NumBytes != 0) { if (hasFP(MF)) { - MI = BuildMI(PPC::OR, 2, PPC::R1).addReg(PPC::R31).addReg(PPC::R31); - MBB.insert(MBBI, MI); MI = BuildMI(PPC::LWZ, 2, PPC::R31).addSImm(GPRSize).addReg(PPC::R31); MBB.insert(MBBI, MI); } From natebegeman at mac.com Mon Apr 4 17:17:59 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 4 Apr 2005 17:17:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504042217.RAA15118@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.41 -> 1.42 --- Log message: Make sure that arg regs used by the call instruction are marked as such, so that regalloc doesn't cleverly reuse early arg regs loading later arg regs. This fixes almost all outstanding failures in the pattern isel. --- Diffs of the changes: (+25 -15) PPC32ISelPattern.cpp | 40 +++++++++++++++++++++++++--------------- 1 files changed, 25 insertions(+), 15 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.41 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.42 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.41 Mon Apr 4 04:09:00 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Mon Apr 4 17:17:48 2005 @@ -1069,6 +1069,24 @@ Select(N.getOperand(0)); ExprMap[N.getValue(Node->getNumValues()-1)] = 1; + MachineInstr *CallMI; + // Emit the correct call instruction based on the type of symbol called. + if (GlobalAddressSDNode *GASD = + dyn_cast(N.getOperand(1))) { + CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(), + true); + } else if (ExternalSymbolSDNode *ESSDN = + dyn_cast(N.getOperand(1))) { + CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(), + true); + } else { + Tmp1 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1); + BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12); + CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0) + .addReg(PPC::R12); + } + // Load the register args to virtual regs std::vector ArgVR; for(int i = 2, e = Node->getNumOperands(); i < e; ++i) @@ -1083,32 +1101,24 @@ case MVT::i16: case MVT::i32: assert(GPR_idx < 8 && "Too many int args"); - if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) + if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) { BuildMI(BB, PPC::OR,2,GPR[GPR_idx]).addReg(ArgVR[i]).addReg(ArgVR[i]); + CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use); + } ++GPR_idx; break; case MVT::f64: case MVT::f32: assert(FPR_idx < 13 && "Too many fp args"); BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(ArgVR[i]); + CallMI->addRegOperand(FPR[FPR_idx], MachineOperand::Use); ++FPR_idx; break; } } - - // Emit the correct call instruction based on the type of symbol called. - if (GlobalAddressSDNode *GASD = - dyn_cast(N.getOperand(1))) { - BuildMI(BB, PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(), true); - } else if (ExternalSymbolSDNode *ESSDN = - dyn_cast(N.getOperand(1))) { - BuildMI(BB, PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(), true); - } else { - Tmp1 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1); - BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12); - BuildMI(BB, PPC::CALLindirect, 3).addImm(20).addImm(0).addReg(PPC::R12); - } + + // Put the call instruction in the correct place in the MachineBasicBlock + BB->push_back(CallMI); switch (Node->getValueType(0)) { default: assert(0 && "Unknown value type for call result!"); From lattner at cs.uiuc.edu Mon Apr 4 17:22:47 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 4 Apr 2005 17:22:47 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/Andersens/modreftest.ll Message-ID: <200504042222.j34MMl1g005129@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/Andersens: modreftest.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+13 -0) modreftest.ll | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/test/Regression/Analysis/Andersens/modreftest.ll diff -c /dev/null llvm/test/Regression/Analysis/Andersens/modreftest.ll:1.1 *** /dev/null Mon Apr 4 17:22:41 2005 --- llvm/test/Regression/Analysis/Andersens/modreftest.ll Mon Apr 4 17:22:30 2005 *************** *** 0 **** --- 1,13 ---- + ; RUN: llvm-as < %s | opt -anders-aa -load-vn -gcse -instcombine | llvm-dis | grep 'ret bool true' + + %G = internal global int* null + declare int *%ext() + bool %bar() { + %V1 = load int** %G + %X2 = call int *%ext() + %V2 = load int** %G + store int* %X2, int** %G + + %C = seteq int* %V1, %V2 + ret bool %C + } From lattner at cs.uiuc.edu Mon Apr 4 17:23:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 4 Apr 2005 17:23:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/Andersens.cpp Message-ID: <200504042223.j34MNYUJ005144@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: Andersens.cpp updated: 1.21 -> 1.22 --- Log message: do not dereference an extra layer of pointers to determine if an external call can modify a memory location. This fixes test/Regression/Analysis/Andersens/modreftest.ll --- Diffs of the changes: (+5 -12) Andersens.cpp | 17 +++++------------ 1 files changed, 5 insertions(+), 12 deletions(-) Index: llvm/lib/Analysis/IPA/Andersens.cpp diff -u llvm/lib/Analysis/IPA/Andersens.cpp:1.21 llvm/lib/Analysis/IPA/Andersens.cpp:1.22 --- llvm/lib/Analysis/IPA/Andersens.cpp:1.21 Tue Mar 29 14:36:05 2005 +++ llvm/lib/Analysis/IPA/Andersens.cpp Mon Apr 4 17:23:21 2005 @@ -374,19 +374,12 @@ Node *N1 = getNode(P); bool PointsToUniversalSet = false; - for (Node::iterator NI = N1->begin(), E = N1->end(); NI != E; ++NI) { - Node *PN = *NI; - if (PN->begin() == PN->end()) - continue; // P doesn't point to anything. - // Get the first pointee. - Node *FirstPointee = *PN->begin(); - if (FirstPointee == &GraphNodes[UniversalSet]) { - PointsToUniversalSet = true; - break; - } - } + if (N1->begin() == N1->end()) + return NoModRef; // P doesn't point to anything. - if (!PointsToUniversalSet) + // Get the first pointee. + Node *FirstPointee = *N1->begin(); + if (FirstPointee != &GraphNodes[UniversalSet]) return NoModRef; // P doesn't point to the universal set. } From natebegeman at mac.com Mon Apr 4 18:02:02 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 4 Apr 2005 18:02:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Message-ID: <200504042302.SAA15271@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCInstrInfo.td updated: 1.53 -> 1.54 --- Log message: Add support for multiply-add, multiply-sub, and their negated versions --- Diffs of the changes: (+21 -0) PowerPCInstrInfo.td | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.53 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.54 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.53 Fri Apr 1 23:59:34 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Mon Apr 4 18:01:51 2005 @@ -397,6 +397,27 @@ def FMADD : AForm_1<63, 29, 0, 0, 0, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), "fmadd $FRT, $FRA, $FRC, $FRB">; +def FMADDS : AForm_1<59, 29, 0, 0, 0, + (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + "fmadds $FRT, $FRA, $FRC, $FRB">; +def FMSUB : AForm_1<63, 28, 0, 0, 0, + (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + "fmsub $FRT, $FRA, $FRC, $FRB">; +def FMSUBS : AForm_1<59, 28, 0, 0, 0, + (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + "fmsubs $FRT, $FRA, $FRC, $FRB">; +def FNMADD : AForm_1<63, 31, 0, 0, 0, + (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + "fnmadd $FRT, $FRA, $FRC, $FRB">; +def FNMADDS : AForm_1<59, 31, 0, 0, 0, + (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + "fnmadds $FRT, $FRA, $FRC, $FRB">; +def FNMSUB : AForm_1<63, 30, 0, 0, 0, + (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + "fnmsub $FRT, $FRA, $FRC, $FRB">; +def FNMSUBS : AForm_1<59, 30, 0, 0, 0, + (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), + "fnmsubs $FRT, $FRA, $FRC, $FRB">; def FSEL : AForm_1<63, 23, 0, 0, 0, (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB), "fsel $FRT, $FRA, $FRC, $FRB">; From natebegeman at mac.com Mon Apr 4 18:40:47 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 4 Apr 2005 18:40:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504042340.SAA15461@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.42 -> 1.43 --- Log message: Pattern match fp mul-add, mul-sub, neg-mul-add, and neg-mul-sub --- Diffs of the changes: (+56 -4) PPC32ISelPattern.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 56 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.42 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.43 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.42 Mon Apr 4 17:17:48 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Mon Apr 4 18:40:36 2005 @@ -25,6 +25,7 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/ADT/Statistic.h" @@ -432,6 +433,7 @@ namespace { Statistic<>NotLogic("ppc-codegen", "Number of inverted logical ops"); +Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations"); //===--------------------------------------------------------------------===// /// ISel - PPC32 specific code to select PPC32 machine instructions for /// SelectionDAG operations. @@ -783,7 +785,27 @@ } case ISD::FNEG: - if (ISD::FABS == N.getOperand(0).getOpcode()) { + if (!NoExcessFPPrecision && + ISD::ADD == N.getOperand(0).getOpcode() && + N.getOperand(0).Val->hasOneUse() && + ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && + N.getOperand(0).getOperand(0).Val->hasOneUse()) { + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0).getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + } else if (!NoExcessFPPrecision && + ISD::SUB == N.getOperand(0).getOpcode() && + N.getOperand(0).Val->hasOneUse() && + ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && + N.getOperand(0).getOperand(0).Val->hasOneUse()) { + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0).getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + } else if (ISD::FABS == N.getOperand(0).getOpcode()) { Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1); } else { @@ -826,14 +848,44 @@ return Result; } - case ISD::MUL: case ISD::ADD: + if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL && + N.getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } + Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::SUB: + if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL && + N.getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } + Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::MUL: case ISD::SDIV: switch( opcode ) { case ISD::MUL: Opc = DestType == MVT::f64 ? PPC::FMUL : PPC::FMULS; break; - case ISD::ADD: Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS; break; - case ISD::SUB: Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS; break; case ISD::SDIV: Opc = DestType == MVT::f64 ? PPC::FDIV : PPC::FDIVS; break; }; Tmp1 = SelectExpr(N.getOperand(0)); From natebegeman at mac.com Mon Apr 4 19:15:19 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 4 Apr 2005 19:15:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504050015.TAA15666@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.43 -> 1.44 --- Log message: Implement SDIV by power of 2 as srawi/addze rather than load imm, divw --- Diffs of the changes: (+24 -0) PPC32ISelPattern.cpp | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.43 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.44 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.43 Mon Apr 4 18:40:36 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Mon Apr 4 19:15:08 2005 @@ -485,6 +485,18 @@ void SelectBranchCC(SDOperand N); }; +/// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It +/// returns zero when the input is not exactly a power of two. +static unsigned ExactLog2(unsigned Val) { + if (Val == 0 || (Val & (Val-1))) return 0; + unsigned Count = 0; + while (Val != 1) { + Val >>= 1; + ++Count; + } + return Count; +} + /// canUseAsImmediateForOpcode - This method returns a value indicating whether /// the ConstantSDNode N can be used as an immediate to Opcode. The return /// values are either 0, 1 or 2. 0 indicates that either N is not a @@ -520,6 +532,9 @@ if (U && (v >= 0 && v <= 65535)) { Imm = v & 0xFFFF; return 1; } if (!U && (v <= 32767 && v >= -32768)) { Imm = v & 0xFFFF; return 1; } break; + case ISD::SDIV: + if (0 != ExactLog2(v)) { Imm = ExactLog2(v); return 1; } + break; } return 0; } @@ -790,6 +805,7 @@ N.getOperand(0).Val->hasOneUse() && ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && N.getOperand(0).getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1)); Tmp3 = SelectExpr(N.getOperand(0).getOperand(1)); @@ -800,6 +816,7 @@ N.getOperand(0).Val->hasOneUse() && ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && N.getOperand(0).getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1)); Tmp3 = SelectExpr(N.getOperand(0).getOperand(1)); @@ -1385,6 +1402,13 @@ case ISD::SDIV: case ISD::UDIV: + if (1 == canUseAsImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) { + Tmp1 = MakeReg(MVT::i32); + Tmp2 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3); + BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1); + return Result; + } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; From lattner at cs.uiuc.edu Mon Apr 4 20:12:20 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 4 Apr 2005 20:12:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/Andersens.cpp Message-ID: <200504050112.j351CKRR024868@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: Andersens.cpp updated: 1.22 -> 1.23 --- Log message: do not crash when using -debug --- Diffs of the changes: (+4 -0) Andersens.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Analysis/IPA/Andersens.cpp diff -u llvm/lib/Analysis/IPA/Andersens.cpp:1.22 llvm/lib/Analysis/IPA/Andersens.cpp:1.23 --- llvm/lib/Analysis/IPA/Andersens.cpp:1.22 Mon Apr 4 17:23:21 2005 +++ llvm/lib/Analysis/IPA/Andersens.cpp Mon Apr 4 20:12:03 2005 @@ -840,6 +840,8 @@ #if 0 Constraints.push_back(Constraint(Constraint::Copy, getNodeValue(CI), &GraphNodes[UniversalSet])); +#else + getNodeValue(CI); #endif } } else if (isa(Op->getType())) { @@ -848,6 +850,8 @@ Constraints.push_back(Constraint(Constraint::Copy, &GraphNodes[UniversalSet], getNode(CI.getOperand(0)))); +#else + getNode(CI.getOperand(0)); #endif } } From lattner at cs.uiuc.edu Mon Apr 4 21:34:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 4 Apr 2005 21:34:30 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/197.parser/Makefile Message-ID: <200504050234.j352YUmc025153@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/197.parser: Makefile updated: 1.4 -> 1.5 --- Log message: Add this in hopes of getting the program to work by stopping conflicts on isnumber. --- Diffs of the changes: (+5 -0) Makefile | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm-test/External/SPEC/CINT2000/197.parser/Makefile diff -u llvm-test/External/SPEC/CINT2000/197.parser/Makefile:1.4 llvm-test/External/SPEC/CINT2000/197.parser/Makefile:1.5 --- llvm-test/External/SPEC/CINT2000/197.parser/Makefile:1.4 Mon Sep 6 23:18:02 2004 +++ llvm-test/External/SPEC/CINT2000/197.parser/Makefile Mon Apr 4 21:34:16 2005 @@ -3,4 +3,9 @@ STDIN_FILENAME = $(RUN_TYPE).in STDOUT_FILENAME = $(RUN_TYPE).out CPPFLAGS = + +ifeq ($(OS),Darwin) +CPPFLAGS += -D_ANSI_SOURCE=1 +endif + include ../../Makefile.spec2000 From natebegeman at mac.com Mon Apr 4 23:23:11 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 4 Apr 2005 23:23:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PPC32ISelSimple.cpp Message-ID: <200504050423.XAA16543@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.44 -> 1.45 PPC32ISelSimple.cpp updated: 1.132 -> 1.133 --- Log message: Rename canUseAsImmediateForOpcode to getImmediateForOpcode to better indicate that it is not a boolean function. Properly emit the pseudo instruction for conditional branch, so that we can fix up conditional branches whose displacements are too large. Reserve the right amount of opcode space for said pseudo instructions. --- Diffs of the changes: (+27 -21) PPC32ISelPattern.cpp | 40 +++++++++++++++++++++++----------------- PPC32ISelSimple.cpp | 8 ++++---- 2 files changed, 27 insertions(+), 21 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.44 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.45 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.44 Mon Apr 4 19:15:08 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Mon Apr 4 23:22:58 2005 @@ -497,17 +497,17 @@ return Count; } -/// canUseAsImmediateForOpcode - This method returns a value indicating whether +/// getImmediateForOpcode - This method returns a value indicating whether /// the ConstantSDNode N can be used as an immediate to Opcode. The return /// values are either 0, 1 or 2. 0 indicates that either N is not a /// ConstantSDNode, or is not suitable for use by that opcode. A return value /// of 1 indicates that the constant may be used in normal immediate form. A /// return value of 2 indicates that the constant may be used in shifted -/// immediate form. If the return value is nonzero, the constant value is -/// placed in Imm. +/// immediate form. A return value of 3 indicates that log base 2 of the +/// constant may be used. /// -static unsigned canUseAsImmediateForOpcode(SDOperand N, unsigned Opcode, - unsigned& Imm, bool U = false) { +static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode, + unsigned& Imm, bool U = false) { if (N.getOpcode() != ISD::Constant) return 0; int v = (int)cast(N)->getSignExtended(); @@ -533,7 +533,7 @@ if (!U && (v <= 32767 && v >= -32768)) { Imm = v & 0xFFFF; return 1; } break; case ISD::SDIV: - if (0 != ExactLog2(v)) { Imm = ExactLog2(v); return 1; } + if ((Imm = ExactLog2(v))) { return 3; } break; } return 0; @@ -619,10 +619,10 @@ Opc = getBCCForSetCC(SetCC->getCondition(), U); Tmp1 = SelectExpr(SetCC->getOperand(0)); - // Pass the optional argument U to canUseAsImmediateForOpcode for SETCC, + // Pass the optional argument U to getImmediateForOpcode for SETCC, // so that it knows whether the SETCC immediate range is signed or not. - if (1 == canUseAsImmediateForOpcode(SetCC->getOperand(1), ISD::SETCC, - Tmp2, U)) { + if (1 == getImmediateForOpcode(SetCC->getOperand(1), ISD::SETCC, + Tmp2, U)) { if (U) BuildMI(BB, PPC::CMPLWI, 2, PPC::CR0).addReg(Tmp1).addImm(Tmp2); else @@ -647,7 +647,7 @@ unsigned imm = 0, opcode = N.getOpcode(); if (N.getOpcode() == ISD::ADD) { Reg = SelectExpr(N.getOperand(0)); - if (1 == canUseAsImmediateForOpcode(N.getOperand(1), opcode, imm)) { + if (1 == getImmediateForOpcode(N.getOperand(1), opcode, imm)) { offset = imm; return false; } @@ -665,9 +665,15 @@ MachineBasicBlock *Dest = cast(N.getOperand(2))->getBasicBlock(); + // Get the MBB we will fall through to so that we can hand it off to the + // branch selection pass as an argument to the PPC::COND_BRANCH pseudo op. + ilist::iterator It = BB; + MachineBasicBlock *Fallthrough = ++It; + Select(N.getOperand(0)); //chain unsigned Opc = SelectSetCR0(N.getOperand(1)); - BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest); + BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc) + .addMBB(Dest).addMBB(Fallthrough); return; } @@ -1285,7 +1291,7 @@ case ISD::ADD: assert (DestType == MVT::i32 && "Only do arithmetic on i32s!"); Tmp1 = SelectExpr(N.getOperand(0)); - switch(canUseAsImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { + switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { default: assert(0 && "unhandled result code"); case 0: // No immediate Tmp2 = SelectExpr(N.getOperand(1)); @@ -1303,7 +1309,7 @@ case ISD::AND: case ISD::OR: Tmp1 = SelectExpr(N.getOperand(0)); - switch(canUseAsImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { + switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { default: assert(0 && "unhandled result code"); case 0: // No immediate Tmp2 = SelectExpr(N.getOperand(1)); @@ -1364,7 +1370,7 @@ return Result; } Tmp1 = SelectExpr(N.getOperand(0)); - switch(canUseAsImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { + switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { default: assert(0 && "unhandled result code"); case 0: // No immediate Tmp2 = SelectExpr(N.getOperand(1)); @@ -1382,7 +1388,7 @@ case ISD::SUB: Tmp2 = SelectExpr(N.getOperand(1)); - if (1 == canUseAsImmediateForOpcode(N.getOperand(0), opcode, Tmp1)) + if (1 == getImmediateForOpcode(N.getOperand(0), opcode, Tmp1)) BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp2).addSImm(Tmp1); else { Tmp1 = SelectExpr(N.getOperand(0)); @@ -1392,7 +1398,7 @@ case ISD::MUL: Tmp1 = SelectExpr(N.getOperand(0)); - if (1 == canUseAsImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) + if (1 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2); else { Tmp2 = SelectExpr(N.getOperand(1)); @@ -1402,7 +1408,7 @@ case ISD::SDIV: case ISD::UDIV: - if (1 == canUseAsImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) { + if (3 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) { Tmp1 = MakeReg(MVT::i32); Tmp2 = SelectExpr(N.getOperand(0)); BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3); Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.132 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.133 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.132 Wed Mar 30 13:38:35 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Mon Apr 4 23:22:58 2005 @@ -1585,11 +1585,11 @@ .addImm(0); if (BI.getSuccessor(1) == NextBB) { if (BI.getSuccessor(0) != NextBB) - BuildMI(BB, PPC::COND_BRANCH, 3).addReg(PPC::CR0).addImm(PPC::BNE) + BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(PPC::BNE) .addMBB(MBBMap[BI.getSuccessor(0)]) .addMBB(MBBMap[BI.getSuccessor(1)]); } else { - BuildMI(BB, PPC::COND_BRANCH, 3).addReg(PPC::CR0).addImm(PPC::BEQ) + BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(PPC::BEQ) .addMBB(MBBMap[BI.getSuccessor(1)]) .addMBB(MBBMap[BI.getSuccessor(0)]); if (BI.getSuccessor(0) != NextBB) @@ -1604,7 +1604,7 @@ OpNum = EmitComparison(OpNum, SCI->getOperand(0), SCI->getOperand(1), BB,MII); if (BI.getSuccessor(0) != NextBB) { - BuildMI(BB, PPC::COND_BRANCH, 3).addReg(PPC::CR0).addImm(Opcode) + BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opcode) .addMBB(MBBMap[BI.getSuccessor(0)]) .addMBB(MBBMap[BI.getSuccessor(1)]); if (BI.getSuccessor(1) != NextBB) @@ -1613,7 +1613,7 @@ // Change to the inverse condition... if (BI.getSuccessor(1) != NextBB) { Opcode = PPC32InstrInfo::invertPPCBranchOpcode(Opcode); - BuildMI(BB, PPC::COND_BRANCH, 3).addReg(PPC::CR0).addImm(Opcode) + BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opcode) .addMBB(MBBMap[BI.getSuccessor(1)]) .addMBB(MBBMap[BI.getSuccessor(0)]); } From natebegeman at mac.com Mon Apr 4 23:32:27 2005 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 4 Apr 2005 23:32:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504050432.XAA16594@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.45 -> 1.46 --- Log message: Back out the previous change to SelectBranchCC, since there are cases it could miscompile. A correct solution will be found in the near future. --- Diffs of the changes: (+11 -4) PPC32ISelPattern.cpp | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.45 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.46 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.45 Mon Apr 4 23:22:58 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Mon Apr 4 23:32:16 2005 @@ -667,13 +667,20 @@ // Get the MBB we will fall through to so that we can hand it off to the // branch selection pass as an argument to the PPC::COND_BRANCH pseudo op. - ilist::iterator It = BB; - MachineBasicBlock *Fallthrough = ++It; + //ilist::iterator It = BB; + //MachineBasicBlock *Fallthrough = ++It; Select(N.getOperand(0)); //chain unsigned Opc = SelectSetCR0(N.getOperand(1)); - BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc) - .addMBB(Dest).addMBB(Fallthrough); + // FIXME: Use this once we have something approximating two-way branches + // We cannot currently use this in case the ISel hands us something like + // BRcc MBBx + // BR MBBy + // since the fallthrough basic block for the conditional branch does not start + // with the unconditional branch (it is skipped over). + //BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc) + // .addMBB(Dest).addMBB(Fallthrough); + BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest); return; } From natebegeman at mac.com Tue Apr 5 03:51:27 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 5 Apr 2005 03:51:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp PowerPC.h PowerPCTargetMachine.cpp PPC64ISelSimple.cpp Message-ID: <200504050851.DAA06279@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC64ISelPattern.cpp added (r1.1) PowerPC.h updated: 1.12 -> 1.13 PowerPCTargetMachine.cpp updated: 1.48 -> 1.49 PPC64ISelSimple.cpp (r1.18) removed --- Log message: Remove 64 bit simple ISel, it never worked correctly Add initial (buggy) implementation of 64 bit pattern ISel --- Diffs of the changes: (+1769 -2) PPC64ISelPattern.cpp | 1767 +++++++++++++++++++++++++++++++++++++++++++++++ PowerPC.h | 2 PowerPCTargetMachine.cpp | 2 3 files changed, 1769 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp diff -c /dev/null llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.1 *** /dev/null Tue Apr 5 03:51:25 2005 --- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Tue Apr 5 03:51:15 2005 *************** *** 0 **** --- 1,1767 ---- + //===-- PPC32ISelPattern.cpp - A pattern matching inst selector for PPC32 -===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Nate Begeman and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines a pattern matching instruction selector for 32 bit PowerPC. + // + //===----------------------------------------------------------------------===// + + #include "PowerPC.h" + #include "PowerPCInstrBuilder.h" + #include "PowerPCInstrInfo.h" + #include "PPC64RegisterInfo.h" + #include "llvm/Constants.h" // FIXME: REMOVE + #include "llvm/Function.h" + #include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/CodeGen/SelectionDAGISel.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/Target/TargetData.h" + #include "llvm/Target/TargetLowering.h" + #include "llvm/Target/TargetOptions.h" + #include "llvm/Support/Debug.h" + #include "llvm/Support/MathExtras.h" + #include "llvm/ADT/Statistic.h" + #include + #include + using namespace llvm; + + //===----------------------------------------------------------------------===// + // PPC32TargetLowering - PPC32 Implementation of the TargetLowering interface + namespace { + class PPC64TargetLowering : public TargetLowering { + int VarArgsFrameIndex; // FrameIndex for start of varargs area. + int ReturnAddrIndex; // FrameIndex for return slot. + public: + PPC64TargetLowering(TargetMachine &TM) : TargetLowering(TM) { + // Set up the register classes. + addRegisterClass(MVT::i64, PPC64::GPRCRegisterClass); + addRegisterClass(MVT::f32, PPC64::FPRCRegisterClass); + addRegisterClass(MVT::f64, PPC64::FPRCRegisterClass); + + // PowerPC has no intrinsics for these particular operations + setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); + setOperationAction(ISD::MEMSET, MVT::Other, Expand); + setOperationAction(ISD::MEMCPY, MVT::Other, Expand); + + // PPC 64 has i16 and i32 but no i8 (or i1) SEXTLOAD + setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand); + setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); + + setShiftAmountFlavor(Extend); // shl X, 32 == 0 + addLegalFPImmediate(+0.0); // Necessary for FSEL + addLegalFPImmediate(-0.0); // + + computeRegisterProperties(); + } + + /// LowerArguments - This hook must be implemented to indicate how we should + /// lower the arguments for the specified function, into the specified DAG. + virtual std::vector + LowerArguments(Function &F, SelectionDAG &DAG); + + /// LowerCallTo - This hook lowers an abstract call to a function into an + /// actual call. + virtual std::pair + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); + + virtual std::pair + LowerVAStart(SDOperand Chain, SelectionDAG &DAG); + + virtual std::pair + LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + const Type *ArgTy, SelectionDAG &DAG); + + virtual std::pair + LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG); + }; + } + + + std::vector + PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { + // + // add beautiful description of PPC stack frame format, or at least some docs + // + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineBasicBlock& BB = MF.front(); + std::vector ArgValues; + + // Due to the rather complicated nature of the PowerPC ABI, rather than a + // fixed size array of physical args, for the sake of simplicity let the STL + // handle tracking them for us. + std::vector argVR, argPR, argOp; + unsigned ArgOffset = 24; + unsigned GPR_remaining = 8; + unsigned FPR_remaining = 13; + unsigned GPR_idx = 0, FPR_idx = 0; + static const unsigned GPR[] = { + PPC::R3, PPC::R4, PPC::R5, PPC::R6, + PPC::R7, PPC::R8, PPC::R9, PPC::R10, + }; + static const unsigned FPR[] = { + PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, + PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 + }; + + // Add DAG nodes to load the arguments... On entry to a function on PPC, + // the arguments start at offset 24, although they are likely to be passed + // in registers. + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { + SDOperand newroot, argt; + unsigned ObjSize; + bool needsLoad = false; + MVT::ValueType ObjectVT = getValueType(I->getType()); + + switch (ObjectVT) { + default: assert(0 && "Unhandled argument type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + ObjSize = 4; + if (GPR_remaining > 0) { + BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); + argt = newroot = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, + DAG.getRoot()); + if (ObjectVT != MVT::i32) + argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, newroot); + } else { + needsLoad = true; + } + break; + case MVT::i64: ObjSize = 8; + // FIXME: can split 64b load between reg/mem if it is last arg in regs + if (GPR_remaining > 1) { + BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); + BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx+1]); + // Copy the extracted halves into the virtual registers + SDOperand argHi = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, + DAG.getRoot()); + SDOperand argLo = DAG.getCopyFromReg(GPR[GPR_idx+1], MVT::i32, argHi); + // Build the outgoing arg thingy + argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi); + newroot = argLo; + } else { + needsLoad = true; + } + break; + case MVT::f32: ObjSize = 4; + case MVT::f64: ObjSize = 8; + if (FPR_remaining > 0) { + BuildMI(&BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]); + argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT, + DAG.getRoot()); + --FPR_remaining; + ++FPR_idx; + } else { + needsLoad = true; + } + break; + } + + // We need to load the argument to a virtual register if we determined above + // that we ran out of physical registers of the appropriate type + if (needsLoad) { + unsigned SubregOffset = 0; + if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3; + if (ObjectVT == MVT::i16) SubregOffset = 2; + int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, + DAG.getConstant(SubregOffset, MVT::i32)); + argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN); + } + + // Every 4 bytes of argument space consumes one of the GPRs available for + // argument passing. + if (GPR_remaining > 0) { + unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1; + GPR_remaining -= delta; + GPR_idx += delta; + } + ArgOffset += ObjSize; + + DAG.setRoot(newroot.getValue(1)); + ArgValues.push_back(argt); + } + + // If the function takes variable number of arguments, make a frame index for + // the start of the first vararg value... for expansion of llvm.va_start. + if (F.isVarArg()) { + VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); + // If this function is vararg, store any remaining integer argument regs + // to their spots on the stack so that they may be loaded by deferencing the + // result of va_next. + std::vector MemOps; + for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) { + BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); + SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot()); + SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), + Val, FIN); + MemOps.push_back(Store); + // Increment the address by four for the next argument to store + SDOperand PtrOff = DAG.getConstant(4, getPointerTy()); + FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff); + } + DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps)); + } + + return ArgValues; + } + + std::pair + PPC64TargetLowering::LowerCallTo(SDOperand Chain, + const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { + // args_to_use will accumulate outgoing args for the ISD::CALL case in + // SelectExpr to use to put the arguments in the appropriate registers. + std::vector args_to_use; + + // Count how many bytes are to be pushed on the stack, including the linkage + // area, and parameter passing area. + unsigned NumBytes = 24; + + if (Args.empty()) { + Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + } else { + for (unsigned i = 0, e = Args.size(); i != e; ++i) + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unknown value type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::f32: + NumBytes += 4; + break; + case MVT::i64: + case MVT::f64: + NumBytes += 8; + break; + } + + // Just to be safe, we'll always reserve the full 24 bytes of linkage area + // plus 32 bytes of argument space in case any called code gets funky on us. + if (NumBytes < 56) NumBytes = 56; + + // Adjust the stack pointer for the new arguments... + // These operations are automatically eliminated by the prolog/epilog pass + Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + + // Set up a copy of the stack pointer for use loading and storing any + // arguments that may not fit in the registers available for argument + // passing. + SDOperand StackPtr = DAG.getCopyFromReg(PPC::R1, MVT::i32, + DAG.getEntryNode()); + + // Figure out which arguments are going to go in registers, and which in + // memory. Also, if this is a vararg function, floating point operations + // must be stored to our stack, and loaded into integer regs as well, if + // any integer regs are available for argument passing. + unsigned ArgOffset = 24; + unsigned GPR_remaining = 8; + unsigned FPR_remaining = 13; + + std::vector MemOps; + for (unsigned i = 0, e = Args.size(); i != e; ++i) { + // PtrOff will be used to store the current argument to the stack if a + // register cannot be found for it. + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + MVT::ValueType ArgVT = getValueType(Args[i].second); + + switch (ArgVT) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + // Promote the integer to 32 bits. If the input type is signed use a + // sign extend, otherwise use a zero extend. + if (Args[i].second->isSigned()) + Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); + else + Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); + // FALL THROUGH + case MVT::i32: + if (GPR_remaining > 0) { + args_to_use.push_back(Args[i].first); + --GPR_remaining; + } else { + MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff)); + } + ArgOffset += 4; + break; + case MVT::i64: + // If we have one free GPR left, we can place the upper half of the i64 + // in it, and store the other half to the stack. If we have two or more + // free GPRs, then we can pass both halves of the i64 in registers. + if (GPR_remaining > 0) { + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(1, MVT::i32)); + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(0, MVT::i32)); + args_to_use.push_back(Hi); + --GPR_remaining; + if (GPR_remaining > 0) { + args_to_use.push_back(Lo); + --GPR_remaining; + } else { + SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); + MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Lo, PtrOff)); + } + } else { + MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff)); + } + ArgOffset += 8; + break; + case MVT::f32: + case MVT::f64: + if (FPR_remaining > 0) { + args_to_use.push_back(Args[i].first); + --FPR_remaining; + if (isVarArg) { + SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff); + MemOps.push_back(Store); + // Float varargs are always shadowed in available integer registers + if (GPR_remaining > 0) { + SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff); + MemOps.push_back(Load); + args_to_use.push_back(Load); + --GPR_remaining; + } + if (GPR_remaining > 0 && MVT::f64 == ArgVT) { + SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); + SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff); + MemOps.push_back(Load); + args_to_use.push_back(Load); + --GPR_remaining; + } + } else { + // If we have any FPRs remaining, we may also have GPRs remaining. + // Args passed in FPRs consume either 1 (f32) or 2 (f64) available + // GPRs. + if (GPR_remaining > 0) { + args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); + --GPR_remaining; + } + if (GPR_remaining > 0 && MVT::f64 == ArgVT) { + args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); + --GPR_remaining; + } + } + } else { + MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff)); + } + ArgOffset += (ArgVT == MVT::f32) ? 4 : 8; + break; + } + } + if (!MemOps.empty()) + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps); + } + + std::vector RetVals; + MVT::ValueType RetTyVT = getValueType(RetTy); + if (RetTyVT != MVT::isVoid) + RetVals.push_back(RetTyVT); + RetVals.push_back(MVT::Other); + + SDOperand TheCall = SDOperand(DAG.getCall(RetVals, + Chain, Callee, args_to_use), 0); + Chain = TheCall.getValue(RetTyVT != MVT::isVoid); + Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + return std::make_pair(TheCall, Chain); + } + + std::pair + PPC64TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { + //vastart just returns the address of the VarArgsFrameIndex slot. + return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32), Chain); + } + + std::pair PPC64TargetLowering:: + LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + const Type *ArgTy, SelectionDAG &DAG) { + MVT::ValueType ArgVT = getValueType(ArgTy); + SDOperand Result; + if (!isVANext) { + Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), VAList); + } else { + unsigned Amt; + if (ArgVT == MVT::i32 || ArgVT == MVT::f32) + Amt = 4; + else { + assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && + "Other types should have been promoted for varargs!"); + Amt = 8; + } + Result = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, + DAG.getConstant(Amt, VAList.getValueType())); + } + return std::make_pair(Result, Chain); + } + + + std::pair PPC64TargetLowering:: + LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG) { + assert(0 && "LowerFrameReturnAddress unimplemented"); + abort(); + } + + namespace { + Statistic<>NotLogic("ppc-codegen", "Number of inverted logical ops"); + Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations"); + //===--------------------------------------------------------------------===// + /// ISel - PPC32 specific code to select PPC32 machine instructions for + /// SelectionDAG operations. + //===--------------------------------------------------------------------===// + class ISel : public SelectionDAGISel { + + /// Comment Here. + PPC64TargetLowering PPC64Lowering; + + /// ExprMap - As shared expressions are codegen'd, we keep track of which + /// vreg the value is produced in, so we only emit one copy of each compiled + /// tree. + std::map ExprMap; + + unsigned GlobalBaseReg; + bool GlobalBaseInitialized; + + public: + ISel(TargetMachine &TM) : SelectionDAGISel(PPC64Lowering), PPC64Lowering(TM) + {} + + /// runOnFunction - Override this function in order to reset our per-function + /// variables. + virtual bool runOnFunction(Function &Fn) { + // Make sure we re-emit a set of the global base reg if necessary + GlobalBaseInitialized = false; + return SelectionDAGISel::runOnFunction(Fn); + } + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { + DEBUG(BB->dump()); + // Codegen the basic block. + Select(DAG.getRoot()); + + // Clear state used for selection. + ExprMap.clear(); + } + + unsigned getGlobalBaseReg(); + unsigned getConstDouble(double floatVal, unsigned Result); + unsigned SelectSetCR0(SDOperand CC); + unsigned SelectExpr(SDOperand N); + unsigned SelectExprFP(SDOperand N, unsigned Result); + void Select(SDOperand N); + + bool SelectAddr(SDOperand N, unsigned& Reg, int& offset); + void SelectBranchCC(SDOperand N); + }; + + /// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It + /// returns zero when the input is not exactly a power of two. + static unsigned ExactLog2(unsigned Val) { + if (Val == 0 || (Val & (Val-1))) return 0; + unsigned Count = 0; + while (Val != 1) { + Val >>= 1; + ++Count; + } + return Count; + } + + /// getImmediateForOpcode - This method returns a value indicating whether + /// the ConstantSDNode N can be used as an immediate to Opcode. The return + /// values are either 0, 1 or 2. 0 indicates that either N is not a + /// ConstantSDNode, or is not suitable for use by that opcode. A return value + /// of 1 indicates that the constant may be used in normal immediate form. A + /// return value of 2 indicates that the constant may be used in shifted + /// immediate form. A return value of 3 indicates that log base 2 of the + /// constant may be used. + /// + static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode, + unsigned& Imm, bool U = false) { + if (N.getOpcode() != ISD::Constant) return 0; + + int v = (int)cast(N)->getSignExtended(); + + switch(Opcode) { + default: return 0; + case ISD::ADD: + if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; } + if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; } + break; + case ISD::AND: + case ISD::XOR: + case ISD::OR: + if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; } + if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; } + break; + case ISD::MUL: + case ISD::SUB: + if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; } + break; + case ISD::SETCC: + if (U && (v >= 0 && v <= 65535)) { Imm = v & 0xFFFF; return 1; } + if (!U && (v <= 32767 && v >= -32768)) { Imm = v & 0xFFFF; return 1; } + break; + case ISD::SDIV: + if ((Imm = ExactLog2(v))) { return 3; } + break; + } + return 0; + } + + /// getBCCForSetCC - Returns the PowerPC condition branch mnemonic corresponding + /// to Condition. If the Condition is unordered or unsigned, the bool argument + /// U is set to true, otherwise it is set to false. + static unsigned getBCCForSetCC(unsigned Condition, bool& U) { + U = false; + switch (Condition) { + default: assert(0 && "Unknown condition!"); abort(); + case ISD::SETEQ: return PPC::BEQ; + case ISD::SETNE: return PPC::BNE; + case ISD::SETULT: U = true; + case ISD::SETLT: return PPC::BLT; + case ISD::SETULE: U = true; + case ISD::SETLE: return PPC::BLE; + case ISD::SETUGT: U = true; + case ISD::SETGT: return PPC::BGT; + case ISD::SETUGE: U = true; + case ISD::SETGE: return PPC::BGE; + } + return 0; + } + + /// IndexedOpForOp - Return the indexed variant for each of the PowerPC load + /// and store immediate instructions. + static unsigned IndexedOpForOp(unsigned Opcode) { + switch(Opcode) { + default: assert(0 && "Unknown opcode!"); abort(); + case PPC::LBZ: return PPC::LBZX; case PPC::STB: return PPC::STBX; + case PPC::LHZ: return PPC::LHZX; case PPC::STH: return PPC::STHX; + case PPC::LHA: return PPC::LHAX; case PPC::STW: return PPC::STWX; + case PPC::LWZ: return PPC::LWZX; case PPC::STD: return PPC::STDX; + case PPC::LD: return PPC::LDX; case PPC::STFS: return PPC::STFSX; + case PPC::LFS: return PPC::LFSX; case PPC::STFD: return PPC::STFDX; + case PPC::LFD: return PPC::LFDX; + } + return 0; + } + } + + /// getGlobalBaseReg - Output the instructions required to put the + /// base address to use for accessing globals into a register. + /// + unsigned ISel::getGlobalBaseReg() { + if (!GlobalBaseInitialized) { + // Insert the set of GlobalBaseReg into the first MBB of the function + MachineBasicBlock &FirstMBB = BB->getParent()->front(); + MachineBasicBlock::iterator MBBI = FirstMBB.begin(); + GlobalBaseReg = MakeReg(MVT::i64); + BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR); + BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg).addReg(PPC::LR); + GlobalBaseInitialized = true; + } + return GlobalBaseReg; + } + + /// getConstDouble - Loads a floating point value into a register, via the + /// Constant Pool. Optionally takes a register in which to load the value. + unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) { + unsigned Tmp1 = MakeReg(MVT::i32); + if (0 == Result) Result = MakeReg(MVT::f64); + MachineConstantPool *CP = BB->getParent()->getConstantPool(); + ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, doubleVal); + unsigned CPI = CP->getConstantPoolIndex(CFP); + BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) + .addConstantPoolIndex(CPI); + BuildMI(BB, PPC::LFD, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1); + return Result; + } + + unsigned ISel::SelectSetCR0(SDOperand CC) { + unsigned Opc, Tmp1, Tmp2; + static const unsigned CompareOpcodes[] = + { PPC::FCMPU, PPC::FCMPU, PPC::CMPW, PPC::CMPLW }; + + // If the first operand to the select is a SETCC node, then we can fold it + // into the branch that selects which value to return. + SetCCSDNode* SetCC = dyn_cast(CC.Val); + if (SetCC && CC.getOpcode() == ISD::SETCC) { + bool U; + Opc = getBCCForSetCC(SetCC->getCondition(), U); + Tmp1 = SelectExpr(SetCC->getOperand(0)); + + // Pass the optional argument U to getImmediateForOpcode for SETCC, + // so that it knows whether the SETCC immediate range is signed or not. + if (1 == getImmediateForOpcode(SetCC->getOperand(1), ISD::SETCC, + Tmp2, U)) { + if (U) + BuildMI(BB, PPC::CMPLWI, 2, PPC::CR0).addReg(Tmp1).addImm(Tmp2); + else + BuildMI(BB, PPC::CMPWI, 2, PPC::CR0).addReg(Tmp1).addSImm(Tmp2); + } else { + bool IsInteger = MVT::isInteger(SetCC->getOperand(0).getValueType()); + unsigned CompareOpc = CompareOpcodes[2 * IsInteger + U]; + Tmp2 = SelectExpr(SetCC->getOperand(1)); + BuildMI(BB, CompareOpc, 2, PPC::CR0).addReg(Tmp1).addReg(Tmp2); + } + } else { + Tmp1 = SelectExpr(CC); + BuildMI(BB, PPC::CMPLWI, 2, PPC::CR0).addReg(Tmp1).addImm(0); + Opc = PPC::BNE; + } + return Opc; + } + + /// Check to see if the load is a constant offset from a base register + bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset) + { + unsigned imm = 0, opcode = N.getOpcode(); + if (N.getOpcode() == ISD::ADD) { + Reg = SelectExpr(N.getOperand(0)); + if (1 == getImmediateForOpcode(N.getOperand(1), opcode, imm)) { + offset = imm; + return false; + } + offset = SelectExpr(N.getOperand(1)); + return true; + } + Reg = SelectExpr(N); + offset = 0; + return false; + } + + void ISel::SelectBranchCC(SDOperand N) + { + assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???"); + MachineBasicBlock *Dest = + cast(N.getOperand(2))->getBasicBlock(); + + // Get the MBB we will fall through to so that we can hand it off to the + // branch selection pass as an argument to the PPC::COND_BRANCH pseudo op. + //ilist::iterator It = BB; + //MachineBasicBlock *Fallthrough = ++It; + + Select(N.getOperand(0)); //chain + unsigned Opc = SelectSetCR0(N.getOperand(1)); + // FIXME: Use this once we have something approximating two-way branches + // We cannot currently use this in case the ISel hands us something like + // BRcc MBBx + // BR MBBy + // since the fallthrough basic block for the conditional branch does not start + // with the unconditional branch (it is skipped over). + //BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc) + // .addMBB(Dest).addMBB(Fallthrough); + BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest); + return; + } + + unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) + { + unsigned Tmp1, Tmp2, Tmp3; + unsigned Opc = 0; + SDNode *Node = N.Val; + MVT::ValueType DestType = N.getValueType(); + unsigned opcode = N.getOpcode(); + + switch (opcode) { + default: + Node->dump(); + assert(0 && "Node not handled!\n"); + + case ISD::SELECT: { + // Attempt to generate FSEL. We can do this whenever we have an FP result, + // and an FP comparison in the SetCC node. + SetCCSDNode* SetCC = dyn_cast(N.getOperand(0).Val); + if (SetCC && N.getOperand(0).getOpcode() == ISD::SETCC && + !MVT::isInteger(SetCC->getOperand(0).getValueType()) && + SetCC->getCondition() != ISD::SETEQ && + SetCC->getCondition() != ISD::SETNE) { + MVT::ValueType VT = SetCC->getOperand(0).getValueType(); + Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against + unsigned TV = SelectExpr(N.getOperand(1)); // Use if TRUE + unsigned FV = SelectExpr(N.getOperand(2)); // Use if FALSE + + ConstantFPSDNode *CN = dyn_cast(SetCC->getOperand(1)); + if (CN && (CN->isExactlyValue(-0.0) || CN->isExactlyValue(0.0))) { + switch(SetCC->getCondition()) { + default: assert(0 && "Invalid FSEL condition"); abort(); + case ISD::SETULT: + case ISD::SETLT: + BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(FV).addReg(TV); + return Result; + case ISD::SETUGE: + case ISD::SETGE: + BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(TV).addReg(FV); + return Result; + case ISD::SETUGT: + case ISD::SETGT: { + Tmp2 = MakeReg(VT); + BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1); + BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(FV).addReg(TV); + return Result; + } + case ISD::SETULE: + case ISD::SETLE: { + Tmp2 = MakeReg(VT); + BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1); + BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(TV).addReg(FV); + return Result; + } + } + } else { + Opc = (MVT::f64 == VT) ? PPC::FSUB : PPC::FSUBS; + Tmp2 = SelectExpr(SetCC->getOperand(1)); + Tmp3 = MakeReg(VT); + switch(SetCC->getCondition()) { + default: assert(0 && "Invalid FSEL condition"); abort(); + case ISD::SETULT: + case ISD::SETLT: + BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV); + return Result; + case ISD::SETUGE: + case ISD::SETGE: + BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV); + return Result; + case ISD::SETUGT: + case ISD::SETGT: + BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1); + BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV); + return Result; + case ISD::SETULE: + case ISD::SETLE: + BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1); + BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV); + return Result; + } + } + assert(0 && "Should never get here"); + return 0; + } + + unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE + unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE + Opc = SelectSetCR0(N.getOperand(0)); + + // Create an iterator with which to insert the MBB for copying the false + // value and the MBB to hold the PHI instruction for this SetCC. + MachineBasicBlock *thisMBB = BB; + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + ilist::iterator It = BB; + ++It; + + // thisMBB: + // ... + // TrueVal = ... + // cmpTY cr0, r1, r2 + // bCC copy1MBB + // fallthrough --> copy0MBB + MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); + MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); + BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(sinkMBB); + MachineFunction *F = BB->getParent(); + F->getBasicBlockList().insert(It, copy0MBB); + F->getBasicBlockList().insert(It, sinkMBB); + // Update machine-CFG edges + BB->addSuccessor(copy0MBB); + BB->addSuccessor(sinkMBB); + + // copy0MBB: + // %FalseValue = ... + // # fallthrough to sinkMBB + BB = copy0MBB; + // Update machine-CFG edges + BB->addSuccessor(sinkMBB); + + // sinkMBB: + // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] + // ... + BB = sinkMBB; + BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue) + .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB); + return Result; + } + + case ISD::FNEG: + if (!NoExcessFPPrecision && + ISD::ADD == N.getOperand(0).getOpcode() && + N.getOperand(0).Val->hasOneUse() && + ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && + N.getOperand(0).getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0).getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + } else if (!NoExcessFPPrecision && + ISD::SUB == N.getOperand(0).getOpcode() && + N.getOperand(0).Val->hasOneUse() && + ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && + N.getOperand(0).getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0).getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + } else if (ISD::FABS == N.getOperand(0).getOpcode()) { + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1); + } else { + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1); + } + return Result; + + case ISD::FABS: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1); + return Result; + + case ISD::FP_ROUND: + assert (DestType == MVT::f32 && + N.getOperand(0).getValueType() == MVT::f64 && + "only f64 to f32 conversion supported here"); + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FRSP, 1, Result).addReg(Tmp1); + return Result; + + case ISD::FP_EXTEND: + assert (DestType == MVT::f64 && + N.getOperand(0).getValueType() == MVT::f32 && + "only f32 to f64 conversion supported here"); + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1); + return Result; + + case ISD::CopyFromReg: + if (Result == 1) + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + Tmp1 = dyn_cast(Node)->getReg(); + BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1); + return Result; + + case ISD::ConstantFP: { + ConstantFPSDNode *CN = cast(N); + Result = getConstDouble(CN->getValue(), Result); + return Result; + } + + case ISD::ADD: + if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL && + N.getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } + Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::SUB: + if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL && + N.getOperand(0).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(1)); + Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } + Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::MUL: + case ISD::SDIV: + switch( opcode ) { + case ISD::MUL: Opc = DestType == MVT::f64 ? PPC::FMUL : PPC::FMULS; break; + case ISD::SDIV: Opc = DestType == MVT::f64 ? PPC::FDIV : PPC::FDIVS; break; + }; + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::UINT_TO_FP: + case ISD::SINT_TO_FP: { + bool IsUnsigned = (ISD::UINT_TO_FP == opcode); + Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register + Tmp2 = MakeReg(MVT::f64); // temp reg to load the integer value into + Tmp3 = MakeReg(MVT::i64); // temp reg to hold the conversion constant + unsigned ConstF = MakeReg(MVT::f64); // temp reg to hold the fp constant + + int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); + MachineConstantPool *CP = BB->getParent()->getConstantPool(); + + // FIXME: pull this FP constant generation stuff out into something like + // the simple ISel's getReg. + if (IsUnsigned) { + addFrameReference(BuildMI(BB, PPC::STD, 3).addReg(Tmp1), FrameIdx); + addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx); + BuildMI(BB, PPC::FCFID, 1, Result).addReg(Tmp2); + } else { + ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, 0x1.000008p52); + unsigned CPI = CP->getConstantPoolIndex(CFP); + // Load constant fp value + unsigned Tmp4 = MakeReg(MVT::i32); + unsigned TmpL = MakeReg(MVT::i32); + BuildMI(BB, PPC::LOADHiAddr, 2, Tmp4).addReg(getGlobalBaseReg()) + .addConstantPoolIndex(CPI); + BuildMI(BB, PPC::LFD, 2, ConstF).addConstantPoolIndex(CPI).addReg(Tmp4); + // Store the hi & low halves of the fp value, currently in int regs + BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330); + addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx); + BuildMI(BB, PPC::XORIS, 2, TmpL).addReg(Tmp1).addImm(0x8000); + addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(TmpL), FrameIdx, 4); + addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx); + // Generate the return value with a subtract + BuildMI(BB, PPC::FSUB, 2, Result).addReg(Tmp2).addReg(ConstF); + } + return Result; + } + } + assert(0 && "Should never get here"); + return 0; + } + + unsigned ISel::SelectExpr(SDOperand N) { + unsigned Result; + unsigned Tmp1, Tmp2, Tmp3; + unsigned Opc = 0; + unsigned opcode = N.getOpcode(); + + SDNode *Node = N.Val; + MVT::ValueType DestType = N.getValueType(); + + unsigned &Reg = ExprMap[N]; + if (Reg) return Reg; + + switch (N.getOpcode()) { + default: + Reg = Result = (N.getValueType() != MVT::Other) ? + MakeReg(N.getValueType()) : 1; + break; + case ISD::CALL: + // If this is a call instruction, make sure to prepare ALL of the result + // values as well as the chain. + if (Node->getNumValues() == 1) + Reg = Result = 1; // Void call, just a chain. + else { + Result = MakeReg(Node->getValueType(0)); + ExprMap[N.getValue(0)] = Result; + for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i) + ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i)); + ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1; + } + break; + } + + if (ISD::CopyFromReg == opcode) + DestType = N.getValue(0).getValueType(); + + if (DestType == MVT::f64 || DestType == MVT::f32) + if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode && ISD::UNDEF != opcode) + return SelectExprFP(N, Result); + + switch (opcode) { + default: + Node->dump(); + assert(0 && "Node not handled!\n"); + case ISD::UNDEF: + BuildMI(BB, PPC::IMPLICIT_DEF, 0, Result); + return Result; + case ISD::DYNAMIC_STACKALLOC: + // Generate both result values. FIXME: Need a better commment here? + if (Result != 1) + ExprMap[N.getValue(1)] = 1; + else + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + + // FIXME: We are currently ignoring the requested alignment for handling + // greater than the stack alignment. This will need to be revisited at some + // point. Align = N.getOperand(2); + if (!isa(N.getOperand(2)) || + cast(N.getOperand(2))->getValue() != 0) { + std::cerr << "Cannot allocate stack object with greater alignment than" + << " the stack alignment yet!"; + abort(); + } + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + // Subtract size from stack pointer, thereby allocating some space. + BuildMI(BB, PPC::SUBF, 2, PPC::R1).addReg(Tmp1).addReg(PPC::R1); + // Put a pointer to the space into the result register by copying the SP + BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R1).addReg(PPC::R1); + return Result; + + case ISD::ConstantPool: + Tmp1 = cast(N)->getIndex(); + Tmp2 = MakeReg(MVT::i64); + BuildMI(BB, PPC::LOADHiAddr, 2, Tmp2).addReg(getGlobalBaseReg()) + .addConstantPoolIndex(Tmp1); + BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp2).addConstantPoolIndex(Tmp1); + return Result; + + case ISD::FrameIndex: + Tmp1 = cast(N)->getIndex(); + addFrameReference(BuildMI(BB, PPC::ADDI, 2, Result), (int)Tmp1, 0, false); + return Result; + + case ISD::GlobalAddress: { + GlobalValue *GV = cast(N)->getGlobal(); + Tmp1 = MakeReg(MVT::i64); + BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) + .addGlobalAddress(GV); + if (GV->hasWeakLinkage() || GV->isExternal()) { + BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1); + } else { + BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp1).addGlobalAddress(GV); + } + return Result; + } + + case ISD::LOAD: + case ISD::EXTLOAD: + case ISD::ZEXTLOAD: + case ISD::SEXTLOAD: { + MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ? + Node->getValueType(0) : cast(Node)->getExtraValueType(); + bool sext = (ISD::SEXTLOAD == opcode); + bool byte = (MVT::i8 == TypeBeingLoaded); + + // Make sure we generate both values. + if (Result != 1) + ExprMap[N.getValue(1)] = 1; // Generate the token + else + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + + SDOperand Chain = N.getOperand(0); + SDOperand Address = N.getOperand(1); + Select(Chain); + + switch (TypeBeingLoaded) { + default: Node->dump(); assert(0 && "Cannot load this type!"); + case MVT::i1: Opc = PPC::LBZ; break; + case MVT::i8: Opc = PPC::LBZ; break; + case MVT::i16: Opc = sext ? PPC::LHA : PPC::LHZ; break; + case MVT::i32: Opc = sext ? PPC::LWA : PPC::LWZ; break; + case MVT::i64: Opc = PPC::LD; break; + case MVT::f32: Opc = PPC::LFS; break; + case MVT::f64: Opc = PPC::LFD; break; + } + + if (ConstantPoolSDNode *CP = dyn_cast(Address)) { + Tmp1 = MakeReg(MVT::i64); + int CPI = CP->getIndex(); + BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) + .addConstantPoolIndex(CPI); + BuildMI(BB, Opc, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1); + } + else if(Address.getOpcode() == ISD::FrameIndex) { + Tmp1 = cast(Address)->getIndex(); + addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1); + } else { + int offset; + bool idx = SelectAddr(Address, Tmp1, offset); + if (idx) { + Opc = IndexedOpForOp(Opc); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(offset); + } else { + BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1); + } + } + return Result; + } + + case ISD::CALL: { + unsigned GPR_idx = 0, FPR_idx = 0; + static const unsigned GPR[] = { + PPC::R3, PPC::R4, PPC::R5, PPC::R6, + PPC::R7, PPC::R8, PPC::R9, PPC::R10, + }; + static const unsigned FPR[] = { + PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, + PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 + }; + + // Lower the chain for this call. + Select(N.getOperand(0)); + ExprMap[N.getValue(Node->getNumValues()-1)] = 1; + + MachineInstr *CallMI; + // Emit the correct call instruction based on the type of symbol called. + if (GlobalAddressSDNode *GASD = + dyn_cast(N.getOperand(1))) { + CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(), + true); + } else if (ExternalSymbolSDNode *ESSDN = + dyn_cast(N.getOperand(1))) { + CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(), + true); + } else { + Tmp1 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1); + BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12); + CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0) + .addReg(PPC::R12); + } + + // Load the register args to virtual regs + std::vector ArgVR; + for(int i = 2, e = Node->getNumOperands(); i < e; ++i) + ArgVR.push_back(SelectExpr(N.getOperand(i))); + + // Copy the virtual registers into the appropriate argument register + for(int i = 0, e = ArgVR.size(); i < e; ++i) { + switch(N.getOperand(i+2).getValueType()) { + default: Node->dump(); assert(0 && "Unknown value type for call"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + assert(GPR_idx < 8 && "Too many int args"); + if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) { + BuildMI(BB, PPC::OR,2,GPR[GPR_idx]).addReg(ArgVR[i]).addReg(ArgVR[i]); + CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use); + } + ++GPR_idx; + break; + case MVT::f64: + case MVT::f32: + assert(FPR_idx < 13 && "Too many fp args"); + BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(ArgVR[i]); + CallMI->addRegOperand(FPR[FPR_idx], MachineOperand::Use); + ++FPR_idx; + break; + } + } + + // Put the call instruction in the correct place in the MachineBasicBlock + BB->push_back(CallMI); + + switch (Node->getValueType(0)) { + default: assert(0 && "Unknown value type for call result!"); + case MVT::Other: return 1; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3).addReg(PPC::R3); + break; + case MVT::f32: + case MVT::f64: + BuildMI(BB, PPC::FMR, 1, Result).addReg(PPC::F1); + break; + } + return Result+N.ResNo; + } + + case ISD::SIGN_EXTEND: + case ISD::SIGN_EXTEND_INREG: + Tmp1 = SelectExpr(N.getOperand(0)); + switch(cast(Node)->getExtraValueType()) { + default: Node->dump(); assert(0 && "Unhandled SIGN_EXTEND type"); break; + case MVT::i32: + BuildMI(BB, PPC::EXTSW, 1, Result).addReg(Tmp1); + break; + case MVT::i16: + BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1); + break; + case MVT::i8: + BuildMI(BB, PPC::EXTSB, 1, Result).addReg(Tmp1); + break; + case MVT::i1: + BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp1).addSImm(0); + break; + } + return Result; + + case ISD::ZERO_EXTEND_INREG: + Tmp1 = SelectExpr(N.getOperand(0)); + switch(cast(Node)->getExtraValueType()) { + default: Node->dump(); assert(0 && "Unhandled ZERO_EXTEND type"); break; + case MVT::i16: Tmp2 = 16; break; + case MVT::i8: Tmp2 = 24; break; + case MVT::i1: Tmp2 = 31; break; + } + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(0).addImm(Tmp2) + .addImm(31); + return Result; + + case ISD::CopyFromReg: + if (Result == 1) + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + Tmp1 = dyn_cast(Node)->getReg(); + BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1); + return Result; + + case ISD::SHL: + Tmp1 = SelectExpr(N.getOperand(0)); + if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { + Tmp2 = CN->getValue() & 0x1F; + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(Tmp2).addImm(0) + .addImm(31-Tmp2); + } else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::SLW, 2, Result).addReg(Tmp1).addReg(Tmp2); + } + return Result; + + case ISD::SRL: + Tmp1 = SelectExpr(N.getOperand(0)); + if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { + Tmp2 = CN->getValue() & 0x1F; + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(32-Tmp2) + .addImm(Tmp2).addImm(31); + } else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::SRW, 2, Result).addReg(Tmp1).addReg(Tmp2); + } + return Result; + + case ISD::SRA: + Tmp1 = SelectExpr(N.getOperand(0)); + if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { + Tmp2 = CN->getValue() & 0x1F; + BuildMI(BB, PPC::SRAWI, 2, Result).addReg(Tmp1).addImm(Tmp2); + } else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::SRAW, 2, Result).addReg(Tmp1).addReg(Tmp2); + } + return Result; + + case ISD::ADD: + Tmp1 = SelectExpr(N.getOperand(0)); + switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { + default: assert(0 && "unhandled result code"); + case 0: // No immediate + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case 1: // Low immediate + BuildMI(BB, PPC::ADDI, 2, Result).addReg(Tmp1).addSImm(Tmp2); + break; + case 2: // Shifted immediate + BuildMI(BB, PPC::ADDIS, 2, Result).addReg(Tmp1).addSImm(Tmp2); + break; + } + return Result; + + case ISD::AND: + case ISD::OR: + Tmp1 = SelectExpr(N.getOperand(0)); + switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { + default: assert(0 && "unhandled result code"); + case 0: // No immediate + Tmp2 = SelectExpr(N.getOperand(1)); + switch (opcode) { + case ISD::AND: Opc = PPC::AND; break; + case ISD::OR: Opc = PPC::OR; break; + } + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case 1: // Low immediate + switch (opcode) { + case ISD::AND: Opc = PPC::ANDIo; break; + case ISD::OR: Opc = PPC::ORI; break; + } + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); + break; + case 2: // Shifted immediate + switch (opcode) { + case ISD::AND: Opc = PPC::ANDISo; break; + case ISD::OR: Opc = PPC::ORIS; break; + } + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); + break; + } + return Result; + + case ISD::XOR: { + // Check for EQV: xor, (xor a, -1), b + if (N.getOperand(0).getOpcode() == ISD::XOR && + N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(0).getOperand(1))->isAllOnesValue()) { + ++NotLogic; + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::EQV, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + } + // Check for NOT, NOR, and NAND: xor (copy, or, and), -1 + if (N.getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1))->isAllOnesValue()) { + ++NotLogic; + switch(N.getOperand(0).getOpcode()) { + case ISD::OR: + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + BuildMI(BB, PPC::NOR, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case ISD::AND: + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + BuildMI(BB, PPC::NAND, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + default: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::NOR, 2, Result).addReg(Tmp1).addReg(Tmp1); + break; + } + return Result; + } + Tmp1 = SelectExpr(N.getOperand(0)); + switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { + default: assert(0 && "unhandled result code"); + case 0: // No immediate + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::XOR, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case 1: // Low immediate + BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp1).addImm(Tmp2); + break; + case 2: // Shifted immediate + BuildMI(BB, PPC::XORIS, 2, Result).addReg(Tmp1).addImm(Tmp2); + break; + } + return Result; + } + + case ISD::SUB: + Tmp2 = SelectExpr(N.getOperand(1)); + if (1 == getImmediateForOpcode(N.getOperand(0), opcode, Tmp1)) + BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp2).addSImm(Tmp1); + else { + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1); + } + return Result; + + case ISD::MUL: + Tmp1 = SelectExpr(N.getOperand(0)); + if (1 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) + BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2); + else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::MULLD, 2, Result).addReg(Tmp1).addReg(Tmp2); + } + return Result; + + case ISD::SDIV: + case ISD::UDIV: + if (3 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) { + Tmp1 = MakeReg(MVT::i64); + Tmp2 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3); + BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1); + return Result; + } + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::UREM: + case ISD::SREM: { + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + Tmp3 = MakeReg(MVT::i64); + unsigned Tmp4 = MakeReg(MVT::i64); + Opc = (ISD::UREM == opcode) ? PPC::DIVDU : PPC::DIVD; + BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, PPC::MULLD, 2, Tmp4).addReg(Tmp3).addReg(Tmp2); + BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp4).addReg(Tmp1); + return Result; + } + + case ISD::FP_TO_UINT: + case ISD::FP_TO_SINT: { + bool U = (ISD::FP_TO_UINT == opcode); + Tmp1 = SelectExpr(N.getOperand(0)); + if (!U) { + Tmp2 = MakeReg(MVT::f64); + BuildMI(BB, PPC::FCTIWZ, 1, Tmp2).addReg(Tmp1); + int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); + addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(Tmp2), FrameIdx); + addFrameReference(BuildMI(BB, PPC::LWZ, 2, Result), FrameIdx, 4); + return Result; + } else { + unsigned Zero = getConstDouble(0.0); + unsigned MaxInt = getConstDouble((1LL << 32) - 1); + unsigned Border = getConstDouble(1LL << 31); + unsigned UseZero = MakeReg(MVT::f64); + unsigned UseMaxInt = MakeReg(MVT::f64); + unsigned UseChoice = MakeReg(MVT::f64); + unsigned TmpReg = MakeReg(MVT::f64); + unsigned TmpReg2 = MakeReg(MVT::f64); + unsigned ConvReg = MakeReg(MVT::f64); + unsigned IntTmp = MakeReg(MVT::i32); + unsigned XorReg = MakeReg(MVT::i32); + MachineFunction *F = BB->getParent(); + int FrameIdx = F->getFrameInfo()->CreateStackObject(8, 8); + // Update machine-CFG edges + MachineBasicBlock *XorMBB = new MachineBasicBlock(BB->getBasicBlock()); + MachineBasicBlock *PhiMBB = new MachineBasicBlock(BB->getBasicBlock()); + MachineBasicBlock *OldMBB = BB; + ilist::iterator It = BB; ++It; + F->getBasicBlockList().insert(It, XorMBB); + F->getBasicBlockList().insert(It, PhiMBB); + BB->addSuccessor(XorMBB); + BB->addSuccessor(PhiMBB); + // Convert from floating point to unsigned 32-bit value + // Use 0 if incoming value is < 0.0 + BuildMI(BB, PPC::FSEL, 3, UseZero).addReg(Tmp1).addReg(Tmp1).addReg(Zero); + // Use 2**32 - 1 if incoming value is >= 2**32 + BuildMI(BB, PPC::FSUB, 2, UseMaxInt).addReg(MaxInt).addReg(Tmp1); + BuildMI(BB, PPC::FSEL, 3, UseChoice).addReg(UseMaxInt).addReg(UseZero) + .addReg(MaxInt); + // Subtract 2**31 + BuildMI(BB, PPC::FSUB, 2, TmpReg).addReg(UseChoice).addReg(Border); + // Use difference if >= 2**31 + BuildMI(BB, PPC::FCMPU, 2, PPC::CR0).addReg(UseChoice).addReg(Border); + BuildMI(BB, PPC::FSEL, 3, TmpReg2).addReg(TmpReg).addReg(TmpReg) + .addReg(UseChoice); + // Convert to integer + BuildMI(BB, PPC::FCTIWZ, 1, ConvReg).addReg(TmpReg2); + addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(ConvReg), FrameIdx); + addFrameReference(BuildMI(BB, PPC::LWZ, 2, IntTmp), FrameIdx, 4); + BuildMI(BB, PPC::BLT, 2).addReg(PPC::CR0).addMBB(PhiMBB); + BuildMI(BB, PPC::B, 1).addMBB(XorMBB); + + // XorMBB: + // add 2**31 if input was >= 2**31 + BB = XorMBB; + BuildMI(BB, PPC::XORIS, 2, XorReg).addReg(IntTmp).addImm(0x8000); + XorMBB->addSuccessor(PhiMBB); + + // PhiMBB: + // DestReg = phi [ IntTmp, OldMBB ], [ XorReg, XorMBB ] + BB = PhiMBB; + BuildMI(BB, PPC::PHI, 4, Result).addReg(IntTmp).addMBB(OldMBB) + .addReg(XorReg).addMBB(XorMBB); + return Result; + } + assert(0 && "Should never get here"); + return 0; + } + + case ISD::SETCC: + if (SetCCSDNode *SetCC = dyn_cast(Node)) { + Opc = SelectSetCR0(N); + + unsigned TrueValue = MakeReg(MVT::i32); + BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1); + unsigned FalseValue = MakeReg(MVT::i32); + BuildMI(BB, PPC::LI, 1, FalseValue).addSImm(0); + + // Create an iterator with which to insert the MBB for copying the false + // value and the MBB to hold the PHI instruction for this SetCC. + MachineBasicBlock *thisMBB = BB; + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + ilist::iterator It = BB; + ++It; + + // thisMBB: + // ... + // cmpTY cr0, r1, r2 + // %TrueValue = li 1 + // bCC sinkMBB + MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); + MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); + BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(sinkMBB); + MachineFunction *F = BB->getParent(); + F->getBasicBlockList().insert(It, copy0MBB); + F->getBasicBlockList().insert(It, sinkMBB); + // Update machine-CFG edges + BB->addSuccessor(copy0MBB); + BB->addSuccessor(sinkMBB); + + // copy0MBB: + // %FalseValue = li 0 + // fallthrough + BB = copy0MBB; + // Update machine-CFG edges + BB->addSuccessor(sinkMBB); + + // sinkMBB: + // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] + // ... + BB = sinkMBB; + BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue) + .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB); + return Result; + } + assert(0 && "Is this legal?"); + return 0; + + case ISD::SELECT: { + unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE + unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE + Opc = SelectSetCR0(N.getOperand(0)); + + // Create an iterator with which to insert the MBB for copying the false + // value and the MBB to hold the PHI instruction for this SetCC. + MachineBasicBlock *thisMBB = BB; + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + ilist::iterator It = BB; + ++It; + + // thisMBB: + // ... + // TrueVal = ... + // cmpTY cr0, r1, r2 + // bCC copy1MBB + // fallthrough --> copy0MBB + MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); + MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); + BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(sinkMBB); + MachineFunction *F = BB->getParent(); + F->getBasicBlockList().insert(It, copy0MBB); + F->getBasicBlockList().insert(It, sinkMBB); + // Update machine-CFG edges + BB->addSuccessor(copy0MBB); + BB->addSuccessor(sinkMBB); + + // copy0MBB: + // %FalseValue = ... + // # fallthrough to sinkMBB + BB = copy0MBB; + // Update machine-CFG edges + BB->addSuccessor(sinkMBB); + + // sinkMBB: + // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] + // ... + BB = sinkMBB; + BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue) + .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB); + + // FIXME: Select i64? + return Result; + } + + case ISD::Constant: + switch (N.getValueType()) { + default: assert(0 && "Cannot use constants of this type!"); + case MVT::i1: + BuildMI(BB, PPC::LI, 1, Result) + .addSImm(!cast(N)->isNullValue()); + break; + case MVT::i32: + { + int v = (int)cast(N)->getSignExtended(); + if (v < 32768 && v >= -32768) { + BuildMI(BB, PPC::LI, 1, Result).addSImm(v); + } else { + Tmp1 = MakeReg(MVT::i32); + BuildMI(BB, PPC::LIS, 1, Tmp1).addSImm(v >> 16); + BuildMI(BB, PPC::ORI, 2, Result).addReg(Tmp1).addImm(v & 0xFFFF); + } + } + } + return Result; + } + + return 0; + } + + void ISel::Select(SDOperand N) { + unsigned Tmp1, Tmp2, Opc; + unsigned opcode = N.getOpcode(); + + if (!ExprMap.insert(std::make_pair(N, 1)).second) + return; // Already selected. + + SDNode *Node = N.Val; + + switch (Node->getOpcode()) { + default: + Node->dump(); std::cerr << "\n"; + assert(0 && "Node not handled yet!"); + case ISD::EntryToken: return; // Noop + case ISD::TokenFactor: + for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) + Select(Node->getOperand(i)); + return; + case ISD::ADJCALLSTACKDOWN: + case ISD::ADJCALLSTACKUP: + Select(N.getOperand(0)); + Tmp1 = cast(N.getOperand(1))->getValue(); + Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? PPC::ADJCALLSTACKDOWN : + PPC::ADJCALLSTACKUP; + BuildMI(BB, Opc, 1).addImm(Tmp1); + return; + case ISD::BR: { + MachineBasicBlock *Dest = + cast(N.getOperand(1))->getBasicBlock(); + Select(N.getOperand(0)); + BuildMI(BB, PPC::B, 1).addMBB(Dest); + return; + } + case ISD::BRCOND: + SelectBranchCC(N); + return; + case ISD::CopyToReg: + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + Tmp2 = cast(N)->getReg(); + + if (Tmp1 != Tmp2) { + if (N.getOperand(1).getValueType() == MVT::f64 || + N.getOperand(1).getValueType() == MVT::f32) + BuildMI(BB, PPC::FMR, 1, Tmp2).addReg(Tmp1); + else + BuildMI(BB, PPC::OR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); + } + return; + case ISD::ImplicitDef: + Select(N.getOperand(0)); + BuildMI(BB, PPC::IMPLICIT_DEF, 0, cast(N)->getReg()); + return; + case ISD::RET: + switch (N.getNumOperands()) { + default: + assert(0 && "Unknown return instruction!"); + case 3: + assert(N.getOperand(1).getValueType() == MVT::i32 && + N.getOperand(2).getValueType() == MVT::i32 && + "Unknown two-register value!"); + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + Tmp2 = SelectExpr(N.getOperand(2)); + BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp2).addReg(Tmp2); + BuildMI(BB, PPC::OR, 2, PPC::R4).addReg(Tmp1).addReg(Tmp1); + break; + case 2: + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + switch (N.getOperand(1).getValueType()) { + default: + assert(0 && "Unknown return type!"); + case MVT::f64: + case MVT::f32: + BuildMI(BB, PPC::FMR, 1, PPC::F1).addReg(Tmp1); + break; + case MVT::i32: + BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1); + break; + } + case 1: + Select(N.getOperand(0)); + break; + } + BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction + return; + case ISD::TRUNCSTORE: + case ISD::STORE: + { + SDOperand Chain = N.getOperand(0); + SDOperand Value = N.getOperand(1); + SDOperand Address = N.getOperand(2); + Select(Chain); + + Tmp1 = SelectExpr(Value); //value + + if (opcode == ISD::STORE) { + switch(Value.getValueType()) { + default: assert(0 && "unknown Type in store"); + case MVT::i64: Opc = PPC::STD; break; + case MVT::f64: Opc = PPC::STFD; break; + case MVT::f32: Opc = PPC::STFS; break; + } + } else { //ISD::TRUNCSTORE + switch(cast(Node)->getExtraValueType()) { + default: assert(0 && "unknown Type in store"); + case MVT::i1: //FIXME: DAG does not promote this load + case MVT::i8: Opc= PPC::STB; break; + case MVT::i16: Opc = PPC::STH; break; + case MVT::i32: Opc = PPC::STW; break; + } + } + + if(Address.getOpcode() == ISD::FrameIndex) + { + Tmp2 = cast(Address)->getIndex(); + addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2); + } + else + { + int offset; + bool idx = SelectAddr(Address, Tmp2, offset); + if (idx) { + Opc = IndexedOpForOp(Opc); + BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset); + } else { + BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2); + } + } + return; + } + case ISD::EXTLOAD: + case ISD::SEXTLOAD: + case ISD::ZEXTLOAD: + case ISD::LOAD: + case ISD::CopyFromReg: + case ISD::CALL: + case ISD::DYNAMIC_STACKALLOC: + ExprMap.erase(N); + SelectExpr(N); + return; + } + assert(0 && "Should not be reached!"); + } + + + /// createPPC32PatternInstructionSelector - This pass converts an LLVM function + /// into a machine code representation using pattern matching and a machine + /// description file. + /// + FunctionPass *llvm::createPPC64ISelPattern(TargetMachine &TM) { + return new ISel(TM); + } + Index: llvm/lib/Target/PowerPC/PowerPC.h diff -u llvm/lib/Target/PowerPC/PowerPC.h:1.12 llvm/lib/Target/PowerPC/PowerPC.h:1.13 --- llvm/lib/Target/PowerPC/PowerPC.h:1.12 Wed Mar 23 22:41:43 2005 +++ llvm/lib/Target/PowerPC/PowerPC.h Tue Apr 5 03:51:15 2005 @@ -25,7 +25,7 @@ FunctionPass *createPPCBranchSelectionPass(); FunctionPass *createPPC32ISelSimple(TargetMachine &TM); FunctionPass *createPPC32ISelPattern(TargetMachine &TM); -FunctionPass *createPPC64ISelSimple(TargetMachine &TM); +FunctionPass *createPPC64ISelPattern(TargetMachine &TM); FunctionPass *createDarwinAsmPrinter(std::ostream &OS, TargetMachine &TM); FunctionPass *createAIXAsmPrinter(std::ostream &OS, TargetMachine &TM); Index: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.48 llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.49 --- llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.48 Thu Mar 24 00:28:42 2005 +++ llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Tue Apr 5 03:51:15 2005 @@ -97,7 +97,7 @@ PM.add(createUnreachableBlockEliminationPass()); if (LP64) - PM.add(createPPC64ISelSimple(*this)); + PM.add(createPPC64ISelPattern(*this)); else if (EnablePatternISel) PM.add(createPPC32ISelPattern(*this)); else From tbrethou at cs.uiuc.edu Tue Apr 5 11:37:01 2005 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Tue, 5 Apr 2005 11:37:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp MSchedGraph.h ModuloScheduling.cpp ModuloScheduling.h Message-ID: <200504051637.j35Gb1Zs029769@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/ModuloScheduling: MSchedGraph.cpp updated: 1.16 -> 1.17 MSchedGraph.h updated: 1.9 -> 1.10 ModuloScheduling.cpp updated: 1.45 -> 1.46 ModuloScheduling.h updated: 1.26 -> 1.27 --- Log message: Updated to use dep analyzer. --- Diffs of the changes: (+113 -194) MSchedGraph.cpp | 122 ++++++----------------------------- MSchedGraph.h | 8 +- ModuloScheduling.cpp | 175 +++++++++++++++++++++++++-------------------------- ModuloScheduling.h | 2 4 files changed, 113 insertions(+), 194 deletions(-) Index: llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp diff -u llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp:1.16 llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp:1.17 --- llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp:1.16 Tue Mar 29 14:35:10 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp Tue Apr 5 11:36:44 2005 @@ -141,8 +141,8 @@ //Create a graph for a machine block. The ignoreInstrs map is so that we ignore instructions //associated to the index variable since this is a special case in Modulo Scheduling. //We only want to deal with the body of the loop. -MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, - TargetData &TD, std::map &ignoreInstrs, +MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, + std::map &ignoreInstrs, DependenceAnalyzer &DA, std::map &machineTollvm ) : BB(bb), Target(targ) { @@ -153,7 +153,7 @@ //DEBUG(std::cerr << "Constructing graph for " << bb << "\n"); //Create nodes and edges for this BB - buildNodesAndEdges(AA, TD, ignoreInstrs, DA, machineTollvm); + buildNodesAndEdges(ignoreInstrs, DA, machineTollvm); //Experimental! //addBranchEdges(); @@ -273,8 +273,7 @@ //Add edges between the nodes -void MSchedGraph::buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, - std::map &ignoreInstrs, +void MSchedGraph::buildNodesAndEdges(std::map &ignoreInstrs, DependenceAnalyzer &DA, std::map &machineTollvm) { @@ -411,7 +410,7 @@ } - addMemEdges(memInstructions, AA, TD, DA, machineTollvm); + addMemEdges(memInstructions, DA, machineTollvm); addMachRegEdges(regNumtoNodeMap); //Finally deal with PHI Nodes and Value* @@ -590,8 +589,7 @@ //Add edges between all loads and stores //Can be less strict with alias analysis and data dependence analysis. -void MSchedGraph::addMemEdges(const std::vector& memInst, AliasAnalysis &AA, - TargetData &TD, DependenceAnalyzer &DA, +void MSchedGraph::addMemEdges(const std::vector& memInst, DependenceAnalyzer &DA, std::map &machineTollvm) { //Get Target machine instruction info @@ -610,101 +608,23 @@ for(unsigned destIndex = srcIndex + 1; destIndex < memInst.size(); ++destIndex) { MachineInstr *destInst = (MachineInstr*) memInst[destIndex]->getInst(); - bool malias = false; - + DEBUG(std::cerr << "MInst1: " << *srcInst << "\n"); DEBUG(std::cerr << "Inst1: " << *machineTollvm[srcInst] << "\n"); DEBUG(std::cerr << "MInst2: " << *destInst << "\n"); DEBUG(std::cerr << "Inst2: " << *machineTollvm[destInst] << "\n"); - //Add Anti dependencies (store after load) - //Source is a Load - if(TMI->isLoad(srcNodeOpCode)) { - - //Destination is a store - if(TMI->isStore(destInst->getOpcode())) { - - //Get the Value* that we are reading from the load, always the first op - const MachineOperand &mOp = srcInst->getOperand(0); - const MachineOperand &mOp2 = destInst->getOperand(0); - - if(mOp.hasAllocatedReg()) - if(mOp.getReg() == SparcV9::g0) - continue; - else - malias = true; - if(mOp2.hasAllocatedReg()) - if(mOp2.getReg() == SparcV9::g0) - continue; - else - malias = true; - - //compare to DA - DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst], machineTollvm[destInst]); - - //Only add the edge if we can't verify that they do not alias - if(malias || AA.alias(mOp2.getVRegValue(), - (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()), - mOp.getVRegValue(), - (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType())) - != AliasAnalysis::NoAlias) { - - //Add edge from load to store - memInst[srcIndex]->addOutEdge(memInst[destIndex], - MSchedGraphEdge::MemoryDep, - MSchedGraphEdge::AntiDep); - - assert(dr.dependences.size() == 1 && "Expected at least one dependence\n"); - - } - else - assert(dr.dependences.size() == 0 && "Expected no dependence\n"); - } - } - - //If source is a store, add output and true dependencies - if(TMI->isStore(srcNodeOpCode)) { + DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst], machineTollvm[destInst]); - //Get the Value* that we are reading from the load, always the first op - const MachineOperand &mOp = srcInst->getOperand(0); - const MachineOperand &mOp2 = destInst->getOperand(0); + for(std::vector::iterator d = dr.dependences.begin(), de = dr.dependences.end(); + d != de; ++d) { + //Add edge from load to store + memInst[srcIndex]->addOutEdge(memInst[destIndex], + MSchedGraphEdge::MemoryDep, + d->getDepType(), d->getIteDiff()); - if(mOp.hasAllocatedReg()) - if(mOp.getReg() == SparcV9::g0) - continue; - else - malias = true; - if(mOp2.hasAllocatedReg()) - if(mOp2.getReg() == SparcV9::g0) - continue; - else - malias = true; - - //compare to DA - DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst], machineTollvm[destInst]); - - //Only add the edge if we can't verify that they do not alias - if(malias || AA.alias(mOp2.getVRegValue(), - (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()), - mOp.getVRegValue(), - (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType())) - != AliasAnalysis::NoAlias) { - - if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode())) - memInst[srcIndex]->addOutEdge(memInst[destIndex], - MSchedGraphEdge::MemoryDep, - MSchedGraphEdge::OutputDep); - else - memInst[srcIndex]->addOutEdge(memInst[destIndex], - MSchedGraphEdge::MemoryDep, - MSchedGraphEdge::TrueDep); - assert(dr.dependences.size() == 1 && "Expected at least one dependence\n"); - - } - - else - assert(dr.dependences.size() == 0 && "Expected no dependence\n"); } + } //All instructions before the src in execution order have an iteration delay of 1 @@ -732,16 +652,16 @@ malias = true; //Only add the edge if we can't verify that they do not alias - if(AA.alias(mOp2.getVRegValue(), + /*if(AA.alias(mOp2.getVRegValue(), (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()), mOp.getVRegValue(), (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType())) - != AliasAnalysis::NoAlias) { + != AliasAnalysis::NoAlias) {*/ if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode())) memInst[srcIndex]->addOutEdge(memInst[destIndex], MSchedGraphEdge::MemoryDep, MSchedGraphEdge::AntiDep, 1); - } + //} } if(TMI->isStore(srcNodeOpCode)) { @@ -761,11 +681,11 @@ malias = true; //Only add the edge if we can't verify that they do not alias - if(AA.alias(mOp2.getVRegValue(), + /*if(AA.alias(mOp2.getVRegValue(), (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()), mOp.getVRegValue(), (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType())) - != AliasAnalysis::NoAlias) { + != AliasAnalysis::NoAlias) {*/ if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode())) memInst[srcIndex]->addOutEdge(memInst[destIndex], @@ -775,7 +695,7 @@ memInst[srcIndex]->addOutEdge(memInst[destIndex], MSchedGraphEdge::MemoryDep, MSchedGraphEdge::TrueDep, 1); - } + //} } } Index: llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h diff -u llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h:1.9 llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h:1.10 --- llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h:1.9 Tue Mar 29 14:35:10 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h Tue Apr 5 11:36:44 2005 @@ -241,19 +241,19 @@ //Add Nodes and Edges to this graph for our BB typedef std::pair OpIndexNodePair; - void buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, std::map &ignoreInstrs, DependenceAnalyzer &DA, std::map &machineTollvm); + void buildNodesAndEdges(std::map &ignoreInstrs, DependenceAnalyzer &DA, std::map &machineTollvm); void addValueEdges(std::vector &NodesInMap, MSchedGraphNode *node, bool nodeIsUse, bool nodeIsDef, std::vector &phiInstrs, int diff=0); void addMachRegEdges(std::map >& regNumtoNodeMap); - void addMemEdges(const std::vector& memInst, AliasAnalysis &AA, TargetData &TD, + void addMemEdges(const std::vector& memInst, DependenceAnalyzer &DA, std::map &machineTollvm); void addBranchEdges(); public: - MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, - TargetData &TD, std::map &ignoreInstrs, + MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, + std::map &ignoreInstrs, DependenceAnalyzer &DA, std::map &machineTollvm); //Copy constructor with maps to link old nodes to new nodes Index: llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp diff -u llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp:1.45 llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp:1.46 --- llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp:1.45 Tue Mar 29 14:35:10 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp Tue Apr 5 11:36:44 2005 @@ -153,8 +153,7 @@ MachineFunction &MF = MachineFunction::get(&F); DependenceAnalyzer &DA = getAnalysis(); - AliasAnalysis &AA = getAnalysis(); - TargetData &TD = getAnalysis(); + //Worklist std::vector Worklist; @@ -192,7 +191,7 @@ continue; } - MSchedGraph *MSG = new MSchedGraph(*BI, target, AA, TD, indVarInstrs[*BI], DA, machineTollvm[*BI]); + MSchedGraph *MSG = new MSchedGraph(*BI, target, indVarInstrs[*BI], DA, machineTollvm[*BI]); //Write Graph out to file DEBUG(WriteGraphToFile(std::cerr, F.getName(), MSG)); @@ -260,18 +259,17 @@ //Final scheduling step is to reconstruct the loop only if we actual have //stage > 0 - if(schedule.getMaxStage() != 0 && haveSched) { + if(haveSched) { reconstructLoop(*BI); ++MSLoops; Changed = true; - } - else { - if(!haveSched) - ++NoSched; - else + + if(schedule.getMaxStage() == 0) ++SameStage; - DEBUG(std::cerr << "Max stage is 0, so no change in loop or reached cap\n"); } + else + ++NoSched; + //Clear out our maps for the next basic block that is processed nodeToAttributesMap.clear(); partialOrder.clear(); @@ -437,6 +435,12 @@ //Convert list of LLVM Instructions to list of Machine instructions std::map mIndVar; for(std::set::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) { + + //If we have a load, we can't handle this loop because there is no way to preserve dependences + //between loads and stores + if(isa(*N)) + return false; + MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(*N); for (unsigned j = 0; j < tempMvec.size(); j++) { MachineOpCode OC = (tempMvec[j])->getOpcode(); @@ -449,8 +453,8 @@ } } - //Must have some guts to the loop body - if(mIndVar.size() >= (BI->size()-2)) + //Must have some guts to the loop body (more then 1 instr, dont count nops in size) + if(mIndVar.size() >= (BI->size()-3)) return false; //Put into a map for future access @@ -1332,17 +1336,8 @@ if(PO->count(I->first)) found = true; } - if(!found) { - if(I->first->isBranch() && !I->first->hasPredecessors()) { - if(std::find(branches.begin(), branches.end(), I->first) == branches.end()) - branches.push_back(I->first); - } - else { - lastNodes.insert(I->first); - if(!I->first->hasPredecessors()) - noPredNodes.insert(I->first); - } - } + if(!found) + lastNodes.insert(I->first); } //For each node w/out preds, see if there is a path to one of the @@ -1360,40 +1355,29 @@ //Break up remaining nodes that are not in the partial order ///into their connected compoenents - /*while(lastNodes.size() > 0) { + while(lastNodes.size() > 0) { std::set ccSet; connectedComponentSet(*(lastNodes.begin()),ccSet, lastNodes); if(ccSet.size() > 0) partialOrder.push_back(ccSet); - }*/ - if(lastNodes.size() > 0) - partialOrder.push_back(lastNodes); - - + } + + //Clean up branches by putting them in final order - std::map branchOrder; - for(std::vector::iterator I = branches.begin(), E = branches.end(); I != E; ++I) - branchOrder[(*I)->getIndex()] = *I; - - for(std::map::reverse_iterator I = branchOrder.rbegin(), E = branchOrder.rend(); I != E; ++I) - FinalNodeOrder.push_back(I->second); - + assert(branches.size() == 0 && "We should not have any branches in our graph"); } void ModuloSchedulingPass::connectedComponentSet(MSchedGraphNode *node, std::set &ccSet, std::set &lastNodes) { //Add to final set -if( !ccSet.count(node) && lastNodes.count(node)) { + if( !ccSet.count(node) && lastNodes.count(node)) { lastNodes.erase(node); - if(node->isBranch() && !node->hasPredecessors()) - FinalNodeOrder.push_back(node); - else - ccSet.insert(node); + ccSet.insert(node); } else return; - + //Loop over successors and recurse if we have not seen this node before for(MSchedGraphNode::succ_iterator node_succ = node->succ_begin(), end=node->succ_end(); node_succ != end; ++node_succ) { connectedComponentSet(*node_succ, ccSet, lastNodes); @@ -2552,7 +2536,8 @@ //Write prologue - writePrologues(prologues, BB, llvm_prologues, valuesToSave, newValues, newValLocation); + if(schedule.getMaxStage() != 0) + writePrologues(prologues, BB, llvm_prologues, valuesToSave, newValues, newValLocation); //Print out epilogues and prologue DEBUG(for(std::vector::iterator I = prologues.begin(), E = prologues.end(); @@ -2571,7 +2556,8 @@ std::vector llvm_epilogues; //Write epilogues - writeEpilogues(epilogues, BB, llvm_epilogues, valuesToSave, newValues, newValLocation, kernelPHIs); + if(schedule.getMaxStage() != 0) + writeEpilogues(epilogues, BB, llvm_epilogues, valuesToSave, newValues, newValLocation, kernelPHIs); //Fix our branches @@ -2607,51 +2593,53 @@ const TargetInstrInfo *TMI = target.getInstrInfo(); - //Fix prologue branches - for(unsigned I = 0; I < prologues.size(); ++I) { - - //Find terminator since getFirstTerminator does not work! - for(MachineBasicBlock::reverse_iterator mInst = prologues[I]->rbegin(), mInstEnd = prologues[I]->rend(); mInst != mInstEnd; ++mInst) { - MachineOpCode OC = mInst->getOpcode(); - //If its a branch update its branchto - if(TMI->isBranch(OC)) { - for(unsigned opNum = 0; opNum < mInst->getNumOperands(); ++opNum) { - MachineOperand &mOp = mInst->getOperand(opNum); - if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) { - //Check if we are branching to the kernel, if not branch to epilogue - if(mOp.getVRegValue() == BB->getBasicBlock()) { - if(I == prologues.size()-1) - mOp.setValueReg(llvmKernelBB); - else - mOp.setValueReg(llvm_prologues[I+1]); - } - else { - mOp.setValueReg(llvm_epilogues[(llvm_epilogues.size()-1-I)]); + if(schedule.getMaxStage() != 0) { + //Fix prologue branches + for(unsigned I = 0; I < prologues.size(); ++I) { + + //Find terminator since getFirstTerminator does not work! + for(MachineBasicBlock::reverse_iterator mInst = prologues[I]->rbegin(), mInstEnd = prologues[I]->rend(); mInst != mInstEnd; ++mInst) { + MachineOpCode OC = mInst->getOpcode(); + //If its a branch update its branchto + if(TMI->isBranch(OC)) { + for(unsigned opNum = 0; opNum < mInst->getNumOperands(); ++opNum) { + MachineOperand &mOp = mInst->getOperand(opNum); + if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) { + //Check if we are branching to the kernel, if not branch to epilogue + if(mOp.getVRegValue() == BB->getBasicBlock()) { + if(I == prologues.size()-1) + mOp.setValueReg(llvmKernelBB); + else + mOp.setValueReg(llvm_prologues[I+1]); + } + else { + mOp.setValueReg(llvm_epilogues[(llvm_epilogues.size()-1-I)]); + } } } - } - DEBUG(std::cerr << "New Prologue Branch: " << *mInst << "\n"); + DEBUG(std::cerr << "New Prologue Branch: " << *mInst << "\n"); + } } - } - //Update llvm basic block with our new branch instr - DEBUG(std::cerr << BB->getBasicBlock()->getTerminator() << "\n"); - const BranchInst *branchVal = dyn_cast(BB->getBasicBlock()->getTerminator()); + //Update llvm basic block with our new branch instr + DEBUG(std::cerr << BB->getBasicBlock()->getTerminator() << "\n"); + const BranchInst *branchVal = dyn_cast(BB->getBasicBlock()->getTerminator()); - if(I == prologues.size()-1) { - TerminatorInst *newBranch = new BranchInst(llvmKernelBB, - llvm_epilogues[(llvm_epilogues.size()-1-I)], - branchVal->getCondition(), - llvm_prologues[I]); - } - else - TerminatorInst *newBranch = new BranchInst(llvm_prologues[I+1], - llvm_epilogues[(llvm_epilogues.size()-1-I)], - branchVal->getCondition(), - llvm_prologues[I]); + if(I == prologues.size()-1) { + TerminatorInst *newBranch = new BranchInst(llvmKernelBB, + llvm_epilogues[(llvm_epilogues.size()-1-I)], + branchVal->getCondition(), + llvm_prologues[I]); + } + else + TerminatorInst *newBranch = new BranchInst(llvm_prologues[I+1], + llvm_epilogues[(llvm_epilogues.size()-1-I)], + branchVal->getCondition(), + llvm_prologues[I]); + } } Value *origBranchExit = 0; @@ -2673,6 +2661,8 @@ origBranchExit = mOp.getVRegValue(); mOp.setValueReg(llvm_epilogues[0]); } + else + origBranchExit = mOp.getVRegValue(); } } } @@ -2681,14 +2671,24 @@ //Update kernelLLVM branches const BranchInst *branchVal = dyn_cast(BB->getBasicBlock()->getTerminator()); - assert(llvm_epilogues.size() != 0 && "We must have epilogues!"); + assert(origBranchExit != 0 && "We must have the original bb the kernel exits to!"); - TerminatorInst *newBranch = new BranchInst(llvmKernelBB, - llvm_epilogues[0], - branchVal->getCondition(), - llvmKernelBB); - + if(epilogues.size() > 0) { + TerminatorInst *newBranch = new BranchInst(llvmKernelBB, + llvm_epilogues[0], + branchVal->getCondition(), + llvmKernelBB); + } + else { + BasicBlock *origBBExit = dyn_cast(origBranchExit); + assert(origBBExit !=0 && "Original exit basic block must be set"); + TerminatorInst *newBranch = new BranchInst(llvmKernelBB, + origBBExit, + branchVal->getCondition(), + llvmKernelBB); + } + if(schedule.getMaxStage() != 0) { //Lastly add unconditional branches for the epilogues for(unsigned I = 0; I < epilogues.size(); ++I) { @@ -2720,6 +2720,7 @@ BuildMI(epilogues[I], V9::NOP, 0); } + } //FIX UP Machine BB entry!! //We are looking at the predecesor of our loop basic block and we want to change its ba instruction Index: llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h diff -u llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h:1.26 llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h:1.27 --- llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h:1.26 Tue Mar 29 14:35:10 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h Tue Apr 5 11:36:44 2005 @@ -149,8 +149,6 @@ // getAnalysisUsage virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); - AU.addRequired(); - AU.addRequired(); } }; From natebegeman at mac.com Tue Apr 5 12:32:41 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 5 Apr 2005 12:32:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Message-ID: <200504051732.MAA13860@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC64ISelPattern.cpp updated: 1.1 -> 1.2 --- Log message: Fix cut & paste errors (32->64), and codegen float->int more optimally. --- Diffs of the changes: (+8 -68) PPC64ISelPattern.cpp | 76 +++++---------------------------------------------- 1 files changed, 8 insertions(+), 68 deletions(-) Index: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.1 llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.2 --- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.1 Tue Apr 5 03:51:15 2005 +++ llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Tue Apr 5 12:32:30 2005 @@ -1,4 +1,4 @@ -//===-- PPC32ISelPattern.cpp - A pattern matching inst selector for PPC32 -===// +//===-- PPC64ISelPattern.cpp - A pattern matching inst selector for PPC64 -===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines a pattern matching instruction selector for 32 bit PowerPC. +// This file defines a pattern matching instruction selector for 64 bit PowerPC. // //===----------------------------------------------------------------------===// @@ -1421,73 +1421,13 @@ case ISD::FP_TO_UINT: case ISD::FP_TO_SINT: { - bool U = (ISD::FP_TO_UINT == opcode); Tmp1 = SelectExpr(N.getOperand(0)); - if (!U) { - Tmp2 = MakeReg(MVT::f64); - BuildMI(BB, PPC::FCTIWZ, 1, Tmp2).addReg(Tmp1); - int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); - addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(Tmp2), FrameIdx); - addFrameReference(BuildMI(BB, PPC::LWZ, 2, Result), FrameIdx, 4); - return Result; - } else { - unsigned Zero = getConstDouble(0.0); - unsigned MaxInt = getConstDouble((1LL << 32) - 1); - unsigned Border = getConstDouble(1LL << 31); - unsigned UseZero = MakeReg(MVT::f64); - unsigned UseMaxInt = MakeReg(MVT::f64); - unsigned UseChoice = MakeReg(MVT::f64); - unsigned TmpReg = MakeReg(MVT::f64); - unsigned TmpReg2 = MakeReg(MVT::f64); - unsigned ConvReg = MakeReg(MVT::f64); - unsigned IntTmp = MakeReg(MVT::i32); - unsigned XorReg = MakeReg(MVT::i32); - MachineFunction *F = BB->getParent(); - int FrameIdx = F->getFrameInfo()->CreateStackObject(8, 8); - // Update machine-CFG edges - MachineBasicBlock *XorMBB = new MachineBasicBlock(BB->getBasicBlock()); - MachineBasicBlock *PhiMBB = new MachineBasicBlock(BB->getBasicBlock()); - MachineBasicBlock *OldMBB = BB; - ilist::iterator It = BB; ++It; - F->getBasicBlockList().insert(It, XorMBB); - F->getBasicBlockList().insert(It, PhiMBB); - BB->addSuccessor(XorMBB); - BB->addSuccessor(PhiMBB); - // Convert from floating point to unsigned 32-bit value - // Use 0 if incoming value is < 0.0 - BuildMI(BB, PPC::FSEL, 3, UseZero).addReg(Tmp1).addReg(Tmp1).addReg(Zero); - // Use 2**32 - 1 if incoming value is >= 2**32 - BuildMI(BB, PPC::FSUB, 2, UseMaxInt).addReg(MaxInt).addReg(Tmp1); - BuildMI(BB, PPC::FSEL, 3, UseChoice).addReg(UseMaxInt).addReg(UseZero) - .addReg(MaxInt); - // Subtract 2**31 - BuildMI(BB, PPC::FSUB, 2, TmpReg).addReg(UseChoice).addReg(Border); - // Use difference if >= 2**31 - BuildMI(BB, PPC::FCMPU, 2, PPC::CR0).addReg(UseChoice).addReg(Border); - BuildMI(BB, PPC::FSEL, 3, TmpReg2).addReg(TmpReg).addReg(TmpReg) - .addReg(UseChoice); - // Convert to integer - BuildMI(BB, PPC::FCTIWZ, 1, ConvReg).addReg(TmpReg2); - addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(ConvReg), FrameIdx); - addFrameReference(BuildMI(BB, PPC::LWZ, 2, IntTmp), FrameIdx, 4); - BuildMI(BB, PPC::BLT, 2).addReg(PPC::CR0).addMBB(PhiMBB); - BuildMI(BB, PPC::B, 1).addMBB(XorMBB); - - // XorMBB: - // add 2**31 if input was >= 2**31 - BB = XorMBB; - BuildMI(BB, PPC::XORIS, 2, XorReg).addReg(IntTmp).addImm(0x8000); - XorMBB->addSuccessor(PhiMBB); - - // PhiMBB: - // DestReg = phi [ IntTmp, OldMBB ], [ XorReg, XorMBB ] - BB = PhiMBB; - BuildMI(BB, PPC::PHI, 4, Result).addReg(IntTmp).addMBB(OldMBB) - .addReg(XorReg).addMBB(XorMBB); - return Result; - } - assert(0 && "Should never get here"); - return 0; + Tmp2 = MakeReg(MVT::f64); + BuildMI(BB, PPC::FCTIDZ, 1, Tmp2).addReg(Tmp1); + int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); + addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(Tmp2), FrameIdx); + addFrameReference(BuildMI(BB, PPC::LD, 2, Result), FrameIdx); + return Result; } case ISD::SETCC: From natebegeman at mac.com Tue Apr 5 13:20:01 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 5 Apr 2005 13:20:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Message-ID: <200504051820.NAA14054@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PowerPCAsmPrinter.cpp updated: 1.73 -> 1.74 --- Log message: Behold, rlwinm with certain immediate arguments is printed as the much more readable slwi or srwi (shift left/right word immediate). --- Diffs of the changes: (+22 -0) PowerPCAsmPrinter.cpp | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+) Index: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.73 llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.74 --- llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.73 Tue Mar 29 19:45:43 2005 +++ llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Tue Apr 5 13:19:50 2005 @@ -397,6 +397,28 @@ /// void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { ++EmittedInsts; + // Check for slwi/srwi mnemonics. + if (MI->getOpcode() == PPC::RLWINM) { + bool FoundMnemonic = false; + unsigned char SH = MI->getOperand(2).getImmedValue(); + unsigned char MB = MI->getOperand(3).getImmedValue(); + unsigned char ME = MI->getOperand(4).getImmedValue(); + if (SH <= 31 && MB == 0 && ME == (31-SH)) { + O << "slwi "; FoundMnemonic = true; + } + if (SH <= 31 && MB == (32-SH) && ME == 31) { + O << "srwi "; FoundMnemonic = true; + SH = 32-SH; + } + if (FoundMnemonic) { + printOperand(MI, 0, MVT::i64); + O << ", "; + printOperand(MI, 1, MVT::i64); + O << ", " << (unsigned int)SH << "\n"; + return; + } + } + if (printInstruction(MI)) return; // Printer was automatically generated From lattner at cs.uiuc.edu Tue Apr 5 13:52:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Apr 2005 13:52:03 -0500 Subject: [llvm-commits] CVS: llvm-test/TEST.nightly.report Message-ID: <200504051852.j35Iq3Pk032679@apoc.cs.uiuc.edu> Changes in directory llvm-test: TEST.nightly.report updated: 1.35 -> 1.36 --- Log message: If either of the program runs takes < 0.1s, don't bother printing a ratio. --- Diffs of the changes: (+9 -15) TEST.nightly.report | 24 +++++++++--------------- 1 files changed, 9 insertions(+), 15 deletions(-) Index: llvm-test/TEST.nightly.report diff -u llvm-test/TEST.nightly.report:1.35 llvm-test/TEST.nightly.report:1.36 --- llvm-test/TEST.nightly.report:1.35 Sat Jan 8 15:03:37 2005 +++ llvm-test/TEST.nightly.report Tue Apr 5 13:51:46 2005 @@ -24,33 +24,27 @@ my ($Cols, $Col) = @_; my $GCC = $Cols->[$Col-5]; my $CBE = $Cols->[$Col-4]; - if ($GCC ne "*" and $CBE ne "*" and $CBE != "0") { - return sprintf("%3.2f", $GCC/$CBE); - } else { - return "n/a"; - } + return "n/a" if ($GCC eq "*" or $CBE eq "*"); + return sprintf("%3.2f", $GCC/$CBE) if ($GCC >= 0.1 and $CBE >= 0.1); + return "-"; } sub GCCLLCRatio { my ($Cols, $Col) = @_; my $GCC = $Cols->[$Col-6]; my $LLC = $Cols->[$Col-4]; - if ($GCC ne "*" and $LLC ne "*" and $LLC != "0") { - return sprintf("%3.2f", $GCC/$LLC); - } else { - return "n/a"; - } + return "n/a" if ($GCC eq "*" or $LLC eq "*"); + return sprintf("%3.2f", $GCC/$LLC) if ($GCC >= 0.1 and $LLC >= 0.1); + return "-"; } sub GCCLLC_BETARatio { my ($Cols, $Col) = @_; my $GCC = $Cols->[$Col-7]; my $LLC_BETA = $Cols->[$Col-4]; - if ($GCC ne "*" and $LLC_BETA ne "*" and $LLC_BETA != "0") { - return sprintf("%3.2f", $GCC/$LLC_BETA); - } else { - return "n/a"; - } + return "n/a" if ($GCC eq "*" or $LLC_BETA eq "*"); + return sprintf("%3.2f", $GCC/$LLC_BETA) if ($GCC >= 0.1 and $LLC_BETA >= 0.1); + return "-"; } # These are the columns for the report. The first entry is the header for the From alenhar2 at cs.uiuc.edu Tue Apr 5 15:52:02 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 5 Apr 2005 15:52:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/Alpha.td AlphaISelPattern.cpp Message-ID: <200504052052.j35Kq25H001034@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: Alpha.td updated: 1.2 -> 1.3 AlphaISelPattern.cpp updated: 1.79 -> 1.80 --- Log message: added lowerargs support for varargs --- Diffs of the changes: (+73 -39) Alpha.td | 4 - AlphaISelPattern.cpp | 108 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 73 insertions(+), 39 deletions(-) Index: llvm/lib/Target/Alpha/Alpha.td diff -u llvm/lib/Target/Alpha/Alpha.td:1.2 llvm/lib/Target/Alpha/Alpha.td:1.3 --- llvm/lib/Target/Alpha/Alpha.td:1.2 Fri Feb 4 20:24:26 2005 +++ llvm/lib/Target/Alpha/Alpha.td Tue Apr 5 15:51:46 2005 @@ -44,11 +44,11 @@ //saved regs [R9, R10, R11, R12, R13, R14, //Frame pointer - R15, +// R15, //return address R26, //Stack Pointer - R30, +// R30, F2, F3, F4, F5, F6, F7, F8, F9]; // Pull in Instruction Info: Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.79 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.80 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.79 Sun Apr 3 15:35:21 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Tue Apr 5 15:51:46 2005 @@ -125,17 +125,19 @@ //be passed at 0(SP). //7 ... n 0(SP) ... (n-7)*8(SP) +// //#define FP $15 +// //#define RA $26 +// //#define PV $27 +// //#define GP $29 +// //#define SP $30 + std::vector AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { std::vector ArgValues; - - // //#define FP $15 - // //#define RA $26 - // //#define PV $27 - // //#define GP $29 - // //#define SP $30 - + std::vector LS; + SDOperand Chain = DAG.getRoot(); + // assert(0 && "TODO"); MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo*MFI = MF.getFrameInfo(); @@ -150,47 +152,59 @@ Alpha::R19, Alpha::R20, Alpha::R21}; unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18, Alpha::F19, Alpha::F20, Alpha::F21}; - unsigned argVreg[6]; - unsigned argPreg[6]; - unsigned argOpc[6]; - int count = 0; + //Def incoming registers + { + Function::arg_iterator I = F.arg_begin(); + Function::arg_iterator E = F.arg_end(); + for (int i = 0; i < 6; ++i) + { + if (F.isVarArg()) { + BuildMI(&BB, Alpha::IDEF, 0, args_int[i]); + BuildMI(&BB, Alpha::IDEF, 0, args_float[i]); + } else if (I != E) + { + if(MVT::isInteger(getValueType(I->getType()))) + BuildMI(&BB, Alpha::IDEF, 0, args_int[i]); + else + BuildMI(&BB, Alpha::IDEF, 0, args_float[i]); + ++I; + } + } + } + + BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29); + BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29); + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { SDOperand newroot, argt; if (count < 6) { + unsigned Vreg; + MVT::ValueType VT = getValueType(I->getType()); switch (getValueType(I->getType())) { default: - std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n"; + std::cerr << "Unknown Type " << VT << "\n"; abort(); case MVT::f64: case MVT::f32: - BuildMI(&BB, Alpha::IDEF, 0, args_float[count]); - argVreg[count] = - MF.getSSARegMap()->createVirtualRegister( - getRegClassFor(getValueType(I->getType()))); - argPreg[count] = args_float[count]; - argOpc[count] = Alpha::CPYS; - argt = newroot = DAG.getCopyFromReg(argVreg[count], + Vreg = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(VT)); + BuildMI(&BB, Alpha::CPYS, 2, Vreg).addReg(args_float[count]).addReg(args_float[count]); + argt = newroot = DAG.getCopyFromReg(Vreg, getValueType(I->getType()), - DAG.getRoot()); + Chain); break; case MVT::i1: case MVT::i8: case MVT::i16: case MVT::i32: case MVT::i64: - BuildMI(&BB, Alpha::IDEF, 0, args_int[count]); - argVreg[count] = - MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); - argPreg[count] = args_int[count]; - argOpc[count] = Alpha::BIS; - argt = newroot = - DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot()); + Vreg = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); + BuildMI(&BB, Alpha::BIS, 2, Vreg).addReg(args_int[count]).addReg(args_int[count]); + argt = newroot = DAG.getCopyFromReg(Vreg, MVT::i64, Chain); if (getValueType(I->getType()) != MVT::i64) - argt = - DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot); + argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot); break; } } else { //more args @@ -204,17 +218,37 @@ DAG.getEntryNode(), FIN); } ++count; - DAG.setRoot(newroot.getValue(1)); + LS.push_back(newroot.getValue(1)); ArgValues.push_back(argt); } - BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29); - BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29); - for (int i = 0; i < count && i < 6; ++i) { - BuildMI(&BB, argOpc[i], 2, - argVreg[i]).addReg(argPreg[i]).addReg(argPreg[i]); - } - + // If the functions takes variable number of arguments, copy all regs to stack + if (F.isVarArg()) + for (int i = 0; i < 6; ++i) + { + unsigned Vreg = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); + BuildMI(&BB, Alpha::BIS, 2, Vreg).addReg(args_int[i]).addReg(args_int[i]); + SDOperand argt = DAG.getCopyFromReg(Vreg, MVT::i64, Chain); + int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); + SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64); + LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, argt, SDFI)); + + Vreg = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::f64)); + BuildMI(&BB, Alpha::CPYS, 2, Vreg).addReg(args_float[i]).addReg(args_float[i]); + argt = DAG.getCopyFromReg(Vreg, MVT::f64, Chain); + FI = MFI->CreateFixedObject(8, - 8 * (12 - i)); + SDFI = DAG.getFrameIndex(FI, MVT::i64); + LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, argt, SDFI)); + } + + // If the function takes variable number of arguments, make a frame index for + // the start of the first arg value... for expansion of llvm.va_start. + // if (F.isVarArg()) + // VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); + + //Set up a token factor with all the stack traffic + DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, LS)); + //return the arguments return ArgValues; } From natebegeman at mac.com Tue Apr 5 17:37:07 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 5 Apr 2005 17:37:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504052237.RAA15491@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.58 -> 1.59 --- Log message: Add MULHU and MULHS nodes for the high part of an (un)signed 32x32=64b multiply. --- Diffs of the changes: (+2 -0) SelectionDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.58 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.59 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.58 Fri Apr 1 22:58:41 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Apr 5 17:36:56 2005 @@ -1130,6 +1130,8 @@ case ISD::ADD: return "add"; case ISD::SUB: return "sub"; case ISD::MUL: return "mul"; + case ISD::MULHU: return "mulhu"; + case ISD::MULHS: return "mulhs"; case ISD::SDIV: return "sdiv"; case ISD::UDIV: return "udiv"; case ISD::SREM: return "srem"; From natebegeman at mac.com Tue Apr 5 17:37:08 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 5 Apr 2005 17:37:08 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200504052237.RAA15495@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.27 -> 1.28 --- Log message: Add MULHU and MULHS nodes for the high part of an (un)signed 32x32=64b multiply. --- Diffs of the changes: (+1 -1) SelectionDAGNodes.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.27 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.28 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.27 Fri Apr 1 22:58:28 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Tue Apr 5 17:36:56 2005 @@ -90,7 +90,7 @@ // Simple binary arithmetic operators. - ADD, SUB, MUL, SDIV, UDIV, SREM, UREM, + ADD, SUB, MUL, MULHU, MULHS, SDIV, UDIV, SREM, UREM, // Bitwise operators. AND, OR, XOR, SHL, SRA, SRL, From natebegeman at mac.com Tue Apr 5 19:24:05 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 5 Apr 2005 19:24:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200504060024.TAA15931@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.73 -> 1.74 --- Log message: Expand SREM and UREM for targets that claim not to have them, like PowerPC --- Diffs of the changes: (+25 -2) LegalizeDAG.cpp | 27 +++++++++++++++++++++++++-- 1 files changed, 25 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.73 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.74 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.73 Sun Apr 3 19:57:08 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Apr 5 19:23:54 2005 @@ -854,8 +854,6 @@ case ISD::MUL: case ISD::UDIV: case ISD::SDIV: - case ISD::UREM: - case ISD::SREM: case ISD::AND: case ISD::OR: case ISD::XOR: @@ -868,6 +866,31 @@ Tmp2 != Node->getOperand(1)) Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,Tmp2); break; + + case ISD::UREM: + case ISD::SREM: + Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS + Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS + switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1)) + Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1, + Tmp2); + break; + case TargetLowering::Promote: + case TargetLowering::Custom: + assert(0 && "Cannot promote/custom handle this yet!"); + case TargetLowering::Expand: { + MVT::ValueType VT = Node->getValueType(0); + unsigned Opc = (Node->getOpcode() == ISD::UREM) ? ISD::UDIV : ISD::SDIV; + Result = DAG.getNode(Opc, VT, Tmp1, Tmp2); + Result = DAG.getNode(ISD::MUL, VT, Result, Tmp2); + Result = DAG.getNode(ISD::SUB, VT, Tmp1, Result); + } + break; + } + break; // Unary operators case ISD::FABS: From natebegeman at mac.com Tue Apr 5 19:25:38 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 5 Apr 2005 19:25:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PPC64ISelPattern.cpp PowerPCInstrInfo.td Message-ID: <200504060025.TAA15953@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.46 -> 1.47 PPC64ISelPattern.cpp updated: 1.2 -> 1.3 PowerPCInstrInfo.td updated: 1.54 -> 1.55 --- Log message: Add support for MULHS and MULHU nodes Have LegalizeDAG handle SREM and UREM for us Codegen SDIV and UDIV by constant as a multiply by magic constant instead of integer divide, which is very slow. --- Diffs of the changes: (+194 -21) PPC32ISelPattern.cpp | 212 ++++++++++++++++++++++++++++++++++++++++++++++----- PPC64ISelPattern.cpp | 1 PowerPCInstrInfo.td | 2 3 files changed, 194 insertions(+), 21 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.46 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.47 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.46 Mon Apr 4 23:32:16 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Tue Apr 5 19:25:27 2005 @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// // // This file defines a pattern matching instruction selector for 32 bit PowerPC. +// Magic number generation for integer divide from the PowerPC Compiler Writer's +// Guide, section 3.2.3.5 // //===----------------------------------------------------------------------===// @@ -54,6 +56,10 @@ // PowerPC has an i16 but no i8 (or i1) SEXTLOAD setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand); setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); + + // PowerPC has no SREM/UREM instructions + setOperationAction(ISD::SREM, MVT::i32, Expand); + setOperationAction(ISD::UREM, MVT::i32, Expand); setShiftAmountFlavor(Extend); // shl X, 32 == 0 addLegalFPImmediate(+0.0); // Necessary for FSEL @@ -439,9 +445,10 @@ /// SelectionDAG operations. //===--------------------------------------------------------------------===// class ISel : public SelectionDAGISel { - - /// Comment Here. PPC32TargetLowering PPC32Lowering; + SelectionDAG *ISelDAG; // Hack to support us having a dag->dag transform + // for sdiv and udiv until it is put into the future + // dag combiner. /// ExprMap - As shared expressions are codegen'd, we keep track of which /// vreg the value is produced in, so we only emit one copy of each compiled @@ -452,8 +459,8 @@ bool GlobalBaseInitialized; public: - ISel(TargetMachine &TM) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM) - {} + ISel(TargetMachine &TM) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM), + ISelDAG(0) {} /// runOnFunction - Override this function in order to reset our per-function /// variables. @@ -468,11 +475,17 @@ virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { DEBUG(BB->dump()); // Codegen the basic block. + ISelDAG = &DAG; Select(DAG.getRoot()); // Clear state used for selection. ExprMap.clear(); + ISelDAG = 0; } + + // dag -> dag expanders for integer divide by constant + SDOperand BuildSDIVSequence(SDOperand N); + SDOperand BuildUDIVSequence(SDOperand N); unsigned getGlobalBaseReg(); unsigned getConstDouble(double floatVal, unsigned Result); @@ -504,7 +517,8 @@ /// of 1 indicates that the constant may be used in normal immediate form. A /// return value of 2 indicates that the constant may be used in shifted /// immediate form. A return value of 3 indicates that log base 2 of the -/// constant may be used. +/// constant may be used. A return value of 4 indicates that the constant is +/// suitable for conversion into a magic number for integer division. /// static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode, unsigned& Imm, bool U = false) { @@ -534,6 +548,10 @@ break; case ISD::SDIV: if ((Imm = ExactLog2(v))) { return 3; } + if (v <= -2 || v >= 2) { return 4; } + break; + case ISD::UDIV: + if (v != 0) { return 4; } break; } return 0; @@ -574,6 +592,156 @@ } return 0; } + +// Structure used to return the necessary information to codegen an SDIV as +// a multiply. +struct ms { + int m; // magic number + int s; // shift amount +}; + +struct mu { + unsigned int m; // magic number + int a; // add indicator + int s; // shift amount +}; + +/// magic - calculate the magic numbers required to codegen an integer sdiv as +/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, +/// or -1. +static struct ms magic(int d) { + int p; + unsigned int ad, anc, delta, q1, r1, q2, r2, t; + const unsigned int two31 = 2147483648U; // 2^31 + struct ms mag; + + ad = abs(d); + t = two31 + ((unsigned int)d >> 31); + anc = t - 1 - t%ad; // absolute value of nc + p = 31; // initialize p + q1 = two31/anc; // initialize q1 = 2p/abs(nc) + r1 = two31 - q1*anc; // initialize r1 = rem(2p,abs(nc)) + q2 = two31/ad; // initialize q2 = 2p/abs(d) + r2 = two31 - q2*ad; // initialize r2 = rem(2p,abs(d)) + do { + p = p + 1; + q1 = 2*q1; // update q1 = 2p/abs(nc) + r1 = 2*r1; // update r1 = rem(2p/abs(nc)) + if (r1 >= anc) { // must be unsigned comparison + q1 = q1 + 1; + r1 = r1 - anc; + } + q2 = 2*q2; // update q2 = 2p/abs(d) + r2 = 2*r2; // update r2 = rem(2p/abs(d)) + if (r2 >= ad) { // must be unsigned comparison + q2 = q2 + 1; + r2 = r2 - ad; + } + delta = ad - r2; + } while (q1 < delta || (q1 == delta && r1 == 0)); + + mag.m = q2 + 1; + if (d < 0) mag.m = -mag.m; // resulting magic number + mag.s = p - 32; // resulting shift + return mag; +} + +/// magicu - calculate the magic numbers required to codegen an integer udiv as +/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. +static struct mu magicu(unsigned d) +{ + int p; + unsigned int nc, delta, q1, r1, q2, r2; + struct mu magu; + magu.a = 0; // initialize "add" indicator + nc = - 1 - (-d)%d; + p = 31; // initialize p + q1 = 0x80000000/nc; // initialize q1 = 2p/nc + r1 = 0x80000000 - q1*nc; // initialize r1 = rem(2p,nc) + q2 = 0x7FFFFFFF/d; // initialize q2 = (2p-1)/d + r2 = 0x7FFFFFFF - q2*d; // initialize r2 = rem((2p-1),d) + do { + p = p + 1; + if (r1 >= nc - r1 ) { + q1 = 2*q1 + 1; // update q1 + r1 = 2*r1 - nc; // update r1 + } + else { + q1 = 2*q1; // update q1 + r1 = 2*r1; // update r1 + } + if (r2 + 1 >= d - r2) { + if (q2 >= 0x7FFFFFFF) magu.a = 1; + q2 = 2*q2 + 1; // update q2 + r2 = 2*r2 + 1 - d; // update r2 + } + else { + if (q2 >= 0x80000000) magu.a = 1; + q2 = 2*q2; // update q2 + r2 = 2*r2 + 1; // update r2 + } + delta = d - 1 - r2; + } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); + magu.m = q2 + 1; // resulting magic number + magu.s = p - 32; // resulting shift + return magu; +} +} + +/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, +/// return a DAG expression to select that will generate the same value by +/// multiplying by a magic number. See: +/// +SDOperand ISel::BuildSDIVSequence(SDOperand N) { + int d = (int)cast(N.getOperand(1))->getSignExtended(); + ms magics = magic(d); + // Multiply the numerator (operand 0) by the magic value + SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i32, N.getOperand(0), + ISelDAG->getConstant(magics.m, MVT::i32)); + // If d > 0 and m < 0, add the numerator + if (d > 0 && magics.m < 0) + Q = ISelDAG->getNode(ISD::ADD, MVT::i32, Q, N.getOperand(0)); + // If d < 0 and m > 0, subtract the numerator. + if (d < 0 && magics.m > 0) + Q = ISelDAG->getNode(ISD::SUB, MVT::i32, Q, N.getOperand(0)); + // Shift right algebraic if shift value is nonzero + if (magics.s > 0) + Q = ISelDAG->getNode(ISD::SRA, MVT::i32, Q, + ISelDAG->getConstant(magics.s, MVT::i32)); + // Extract the sign bit and add it to the quotient + SDOperand T = + ISelDAG->getNode(ISD::SRL, MVT::i32, Q, ISelDAG->getConstant(31, MVT::i32)); + Q = ISelDAG->getNode(ISD::ADD, MVT::i32, Q, T); + // Compute the remainder + T = ISelDAG->getNode(ISD::MUL, MVT::i32, Q, N.getOperand(1)); + return ISelDAG->getNode(ISD::SUB, MVT::i32, N.getOperand(0), T); +} + +/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, +/// return a DAG expression to select that will generate the same value by +/// multiplying by a magic number. See: +/// +SDOperand ISel::BuildUDIVSequence(SDOperand N) { + unsigned d = + (unsigned)cast(N.getOperand(1))->getSignExtended(); + mu magics = magicu(d); + // Multiply the numerator (operand 0) by the magic value + SDOperand Q = ISelDAG->getNode(ISD::MULHU, MVT::i32, N.getOperand(0), + ISelDAG->getConstant(magics.m, MVT::i32)); + if (magics.a == 0) { + Q = ISelDAG->getNode(ISD::SRL, MVT::i32, Q, + ISelDAG->getConstant(magics.s, MVT::i32)); + } else { + SDOperand NPQ = ISelDAG->getNode(ISD::SUB, MVT::i32, N.getOperand(0), Q); + NPQ = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ, + ISelDAG->getConstant(1, MVT::i32)); + NPQ = ISelDAG->getNode(ISD::ADD, MVT::i32, NPQ, Q); + Q = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ, + ISelDAG->getConstant(magics.s-1, MVT::i32)); + } + // Compute the remainder + SDOperand T = ISelDAG->getNode(ISD::MUL, MVT::i32, Q, N.getOperand(1)); + return ISelDAG->getNode(ISD::SUB, MVT::i32, N.getOperand(0), T); } /// getGlobalBaseReg - Output the instructions required to put the @@ -1091,7 +1259,6 @@ MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ? Node->getValueType(0) : cast(Node)->getExtraValueType(); bool sext = (ISD::SEXTLOAD == opcode); - bool byte = (MVT::i8 == TypeBeingLoaded); // Make sure we generate both values. if (Result != 1) @@ -1413,14 +1580,32 @@ } return Result; + case ISD::MULHS: + case ISD::MULHU: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + Opc = (ISD::MULHU == opcode) ? PPC::MULHWU : PPC::MULHW; + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + case ISD::SDIV: case ISD::UDIV: - if (3 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) { + switch (getImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) { + default: break; + // If this is an sdiv by a power of two, we can use an srawi/addze pair. + case 3: Tmp1 = MakeReg(MVT::i32); Tmp2 = SelectExpr(N.getOperand(0)); BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3); BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1); return Result; + // If this is a divide by constant, we can emit code using some magic + // constants to implement it as a multiply instead. + case 4: + if (opcode == ISD::SDIV) + return SelectExpr(BuildSDIVSequence(N)); + else + return SelectExpr(BuildUDIVSequence(N)); } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); @@ -1428,19 +1613,6 @@ BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; - case ISD::UREM: - case ISD::SREM: { - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - Tmp3 = MakeReg(MVT::i32); - unsigned Tmp4 = MakeReg(MVT::i32); - Opc = (ISD::UREM == opcode) ? PPC::DIVWU : PPC::DIVW; - BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); - BuildMI(BB, PPC::MULLW, 2, Tmp4).addReg(Tmp3).addReg(Tmp2); - BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp4).addReg(Tmp1); - return Result; - } - case ISD::ADD_PARTS: case ISD::SUB_PARTS: { assert(N.getNumOperands() == 4 && N.getValueType() == MVT::i32 && Index: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.2 llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.3 --- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.2 Tue Apr 5 12:32:30 2005 +++ llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Tue Apr 5 19:25:27 2005 @@ -1069,7 +1069,6 @@ MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ? Node->getValueType(0) : cast(Node)->getExtraValueType(); bool sext = (ISD::SEXTLOAD == opcode); - bool byte = (MVT::i8 == TypeBeingLoaded); // Make sure we generate both values. if (Result != 1) Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.54 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.55 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.54 Mon Apr 4 18:01:51 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Tue Apr 5 19:25:27 2005 @@ -368,6 +368,8 @@ "divw $rT, $rA, $rB">; def DIVWU : XOForm_1<31, 459, 0, 0, 0, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), "divwu $rT, $rA, $rB">; +def MULHW : XOForm_1<31, 75, 0, 0, 0, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), + "mulhw $rT, $rA, $rB">; def MULHWU : XOForm_1<31, 11, 0, 0, 0, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), "mulhwu $rT, $rA, $rB">; def MULLD : XOForm_1<31, 233, 0, 0, 1, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), From natebegeman at mac.com Tue Apr 5 22:36:46 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 5 Apr 2005 22:36:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504060336.WAA16754@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.47 -> 1.48 --- Log message: Turn off the div -> mul optimization until it works correctly 100% of the time. --- Diffs of the changes: (+5 -5) PPC32ISelPattern.cpp | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.47 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.48 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.47 Tue Apr 5 19:25:27 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Tue Apr 5 22:36:33 2005 @@ -1601,11 +1601,11 @@ return Result; // If this is a divide by constant, we can emit code using some magic // constants to implement it as a multiply instead. - case 4: - if (opcode == ISD::SDIV) - return SelectExpr(BuildSDIVSequence(N)); - else - return SelectExpr(BuildUDIVSequence(N)); + //case 4: + // if (opcode == ISD::SDIV) + // return SelectExpr(BuildSDIVSequence(N)); + // else + // return SelectExpr(BuildUDIVSequence(N)); } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); From lattner at cs.uiuc.edu Tue Apr 5 23:19:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Apr 2005 23:19:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp X86InstrInfo.td Message-ID: <200504060419.j364JdsA009921@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.99 -> 1.100 X86InstrInfo.td updated: 1.120 -> 1.121 --- Log message: add signed versions of the extra precision multiplies --- Diffs of the changes: (+16 -0) X86InstrInfo.td | 13 +++++++++++++ X86RegisterInfo.cpp | 3 +++ 2 files changed, 16 insertions(+) Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.99 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.100 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.99 Wed Jan 19 01:50:03 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Tue Apr 5 23:19:22 2005 @@ -149,6 +149,9 @@ case X86::MUL8r: return MakeMInst( X86::MUL8m , FrameIndex, MI); case X86::MUL16r: return MakeMInst( X86::MUL16m, FrameIndex, MI); case X86::MUL32r: return MakeMInst( X86::MUL32m, FrameIndex, MI); + case X86::IMUL8r: return MakeMInst( X86::IMUL8m , FrameIndex, MI); + case X86::IMUL16r: return MakeMInst( X86::IMUL16m, FrameIndex, MI); + case X86::IMUL32r: return MakeMInst( X86::IMUL32m, FrameIndex, MI); case X86::DIV8r: return MakeMInst( X86::DIV8m , FrameIndex, MI); case X86::DIV16r: return MakeMInst( X86::DIV16m, FrameIndex, MI); case X86::DIV32r: return MakeMInst( X86::DIV32m, FrameIndex, MI); Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.120 llvm/lib/Target/X86/X86InstrInfo.td:1.121 --- llvm/lib/Target/X86/X86InstrInfo.td:1.120 Fri Apr 1 22:31:56 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Apr 5 23:19:22 2005 @@ -339,6 +339,19 @@ def MUL32m : I<0xF7, MRM4m, (ops i32mem:$src), "mul{l} $src">, Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*[mem32] +def IMUL8r : I<0xF6, MRM5r, (ops R8:$src), "imul{b} $src">, + Imp<[AL],[AX]>; // AL,AH = AL*R8 +def IMUL16r : I<0xF7, MRM5r, (ops R16:$src), "imul{w} $src">, + Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*R16 +def IMUL32r : I<0xF7, MRM5r, (ops R32:$src), "imul{l} $src">, + Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*R32 +def IMUL8m : I<0xF6, MRM5m, (ops i8mem :$src), + "imul{b} $src">, Imp<[AL],[AX]>; // AL,AH = AL*[mem8] +def IMUL16m : I<0xF7, MRM5m, (ops i16mem:$src), + "imul{w} $src">, Imp<[AX],[AX,DX]>, OpSize;// AX,DX = AX*[mem16] +def IMUL32m : I<0xF7, MRM5m, (ops i32mem:$src), + "imul{l} $src">, Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*[mem32] + // unsigned division/remainder def DIV8r : I<0xF6, MRM6r, (ops R8:$src), // AX/r8 = AL,AH "div{b} $src">, Imp<[AX],[AX]>; From lattner at cs.uiuc.edu Tue Apr 5 23:21:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Apr 2005 23:21:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200504060421.j364LLcV010218@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.99 -> 1.100 --- Log message: Add (untested) support for MULHS and MULHU. --- Diffs of the changes: (+51 -0) X86ISelPattern.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.99 llvm/lib/Target/X86/X86ISelPattern.cpp:1.100 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.99 Fri Apr 1 23:30:17 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Tue Apr 5 23:21:07 2005 @@ -1818,6 +1818,57 @@ BuildMI(BB, X86::FCHS, 1, Result).addReg(Tmp1); return Result; + case ISD::MULHU: + switch (N.getValueType()) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: Tmp2 = X86::MUL8r; break; + case MVT::i16: Tmp2 = X86::MUL16r; break; + case MVT::i32: Tmp2 = X86::MUL32r; break; + } + // FALL THROUGH + case ISD::MULHS: { + unsigned MovOpc, LowReg, HiReg; + switch (N.getValueType()) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: + MovOpc = X86::MOV8rr; + LowReg = X86::AL; + HiReg = X86::AH; + Opc = X86::IMUL8r; + break; + case MVT::i16: + MovOpc = X86::MOV16rr; + LowReg = X86::AX; + HiReg = X86::DX; + Opc = X86::IMUL16r; + break; + case MVT::i32: + MovOpc = X86::MOV32rr; + LowReg = X86::EAX; + HiReg = X86::EDX; + Opc = X86::IMUL32r; + break; + } + if (Node->getOpcode() != ISD::MULHS) + Opc = Tmp2; // Get the MULHU opcode. + + Op0 = Node->getOperand(0); + Op1 = Node->getOperand(1); + if (getRegPressure(Op0) > getRegPressure(Op1)) { + Tmp1 = SelectExpr(Op0); + Tmp2 = SelectExpr(Op1); + } else { + Tmp2 = SelectExpr(Op1); + Tmp1 = SelectExpr(Op0); + } + + // FIXME: Implement folding of loads into the memory operands here! + BuildMI(BB, MovOpc, 1, LowReg).addReg(Tmp1); + BuildMI(BB, Opc, 1).addReg(Tmp2); + BuildMI(BB, MovOpc, 1, Result).addReg(HiReg); + return Result; + } + case ISD::SUB: case ISD::MUL: case ISD::AND: From lattner at cs.uiuc.edu Tue Apr 5 23:21:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 5 Apr 2005 23:21:42 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200504060421.j364LgAv010229@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.28 -> 1.29 --- Log message: document these nodes, as they are nonobvious --- Diffs of the changes: (+5 -1) SelectionDAGNodes.h | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.28 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.29 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.28 Tue Apr 5 17:36:56 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Tue Apr 5 23:21:29 2005 @@ -90,7 +90,11 @@ // Simple binary arithmetic operators. - ADD, SUB, MUL, MULHU, MULHS, SDIV, UDIV, SREM, UREM, + ADD, SUB, MUL, SDIV, UDIV, SREM, UREM, + + // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing + // an unsigned/signed value of type i[2*n], then return the top part. + MULHU, MULHS, // Bitwise operators. AND, OR, XOR, SHL, SRA, SRL, From duraid at octopus.com.au Wed Apr 6 01:18:05 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Wed, 6 Apr 2005 01:18:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64RegisterInfo.td Message-ID: <200504060618.BAA17621@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64RegisterInfo.td updated: 1.1 -> 1.2 --- Log message: make sure 'special' registers don't get allocated --- Diffs of the changes: (+13 -4) IA64RegisterInfo.td | 17 +++++++++++++---- 1 files changed, 13 insertions(+), 4 deletions(-) Index: llvm/lib/Target/IA64/IA64RegisterInfo.td diff -u llvm/lib/Target/IA64/IA64RegisterInfo.td:1.1 llvm/lib/Target/IA64/IA64RegisterInfo.td:1.2 --- llvm/lib/Target/IA64/IA64RegisterInfo.td:1.1 Thu Mar 17 12:17:03 2005 +++ llvm/lib/Target/IA64/IA64RegisterInfo.td Wed Apr 6 01:17:54 2005 @@ -234,9 +234,8 @@ // in IA64RegisterInfo.cpp def GR : RegisterClass; + r120, r121, r122, r123, r124, r125, r126, r127, + r0, r1, r2, r12, r13, r15, r22]> // these last 7 are special (look down) + + { + let Methods = [{ + iterator allocation_order_end(MachineFunction &MF) const { + return end()-7; // 7 special registers + } + }]; +} + // these are the scratch (+stacked) FP registers // ZERO (F0) and ONE (F1) are not here From duraid at octopus.com.au Wed Apr 6 01:18:47 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Wed, 6 Apr 2005 01:18:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64.td Message-ID: <200504060618.BAA17633@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64.td updated: 1.1 -> 1.2 --- Log message: lie a bit and say that r1/r12 (GP/SP) _aren't_ callee-save, as we take care of this ourselves --- Diffs of the changes: (+2 -2) IA64.td | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/IA64/IA64.td diff -u llvm/lib/Target/IA64/IA64.td:1.1 llvm/lib/Target/IA64/IA64.td:1.2 --- llvm/lib/Target/IA64/IA64.td:1.1 Thu Mar 17 12:17:03 2005 +++ llvm/lib/Target/IA64/IA64.td Wed Apr 6 01:18:36 2005 @@ -42,8 +42,8 @@ //'special' GRs: - r1, // global data pointer (GP) - r12, // memory stack pointer (SP) +// r1, // global data pointer (GP) - XXX NOT callee saved, we do it ourselves +// r12, // memory stack pointer (SP)- XXX NOT callee saved, we do it ourselves // **** r13 (thread pointer) we do not touch, ever. it's not here. ****// //r15, // our frame pointer (FP) From natebegeman at mac.com Wed Apr 6 01:45:08 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 6 Apr 2005 01:45:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504060645.BAA17772@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.48 -> 1.49 --- Log message: Fixed version of optimized integer divide is now fixed. Calculate the quotient, not the remainder. Also, make sure to remove the old div operand from the ExprMap and let SelectExpr insert the new one. --- Diffs of the changes: (+9 -13) PPC32ISelPattern.cpp | 22 +++++++++------------- 1 files changed, 9 insertions(+), 13 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.48 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.49 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.48 Tue Apr 5 22:36:33 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Wed Apr 6 01:44:57 2005 @@ -551,7 +551,7 @@ if (v <= -2 || v >= 2) { return 4; } break; case ISD::UDIV: - if (v != 0) { return 4; } + if (v > 1) { return 4; } break; } return 0; @@ -711,10 +711,7 @@ // Extract the sign bit and add it to the quotient SDOperand T = ISelDAG->getNode(ISD::SRL, MVT::i32, Q, ISelDAG->getConstant(31, MVT::i32)); - Q = ISelDAG->getNode(ISD::ADD, MVT::i32, Q, T); - // Compute the remainder - T = ISelDAG->getNode(ISD::MUL, MVT::i32, Q, N.getOperand(1)); - return ISelDAG->getNode(ISD::SUB, MVT::i32, N.getOperand(0), T); + return ISelDAG->getNode(ISD::ADD, MVT::i32, Q, T); } /// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, @@ -739,9 +736,7 @@ Q = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ, ISelDAG->getConstant(magics.s-1, MVT::i32)); } - // Compute the remainder - SDOperand T = ISelDAG->getNode(ISD::MUL, MVT::i32, Q, N.getOperand(1)); - return ISelDAG->getNode(ISD::SUB, MVT::i32, N.getOperand(0), T); + return Q; } /// getGlobalBaseReg - Output the instructions required to put the @@ -1601,11 +1596,12 @@ return Result; // If this is a divide by constant, we can emit code using some magic // constants to implement it as a multiply instead. - //case 4: - // if (opcode == ISD::SDIV) - // return SelectExpr(BuildSDIVSequence(N)); - // else - // return SelectExpr(BuildUDIVSequence(N)); + case 4: + ExprMap.erase(N); + if (opcode == ISD::SDIV) + return SelectExpr(BuildSDIVSequence(N)); + else + return SelectExpr(BuildUDIVSequence(N)); } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); From duraid at octopus.com.au Wed Apr 6 04:54:20 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Wed, 6 Apr 2005 04:54:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64InstrInfo.td Message-ID: <200504060954.EAA29023@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64InstrInfo.td updated: 1.5 -> 1.6 --- Log message: add fms instruction --- Diffs of the changes: (+2 -0) IA64InstrInfo.td | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/IA64/IA64InstrInfo.td diff -u llvm/lib/Target/IA64/IA64InstrInfo.td:1.5 llvm/lib/Target/IA64/IA64InstrInfo.td:1.6 --- llvm/lib/Target/IA64/IA64InstrInfo.td:1.5 Sun Apr 3 23:50:57 2005 +++ llvm/lib/Target/IA64/IA64InstrInfo.td Wed Apr 6 04:54:09 2005 @@ -226,6 +226,8 @@ "mov $dst = $src;;">; // XXX: there _is_ no fmov def FMA : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), "fma $dst = $src1, $src2, $src3;;">; +def FMS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), + "fms $dst = $src1, $src2, $src3;;">; def FNMA : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), "fnma $dst = $src1, $src2, $src3;;">; def FABS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), From duraid at octopus.com.au Wed Apr 6 04:55:28 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Wed, 6 Apr 2005 04:55:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200504060955.EAA29284@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.11 -> 1.12 --- Log message: steal sampo's div-by-constant-power-of-2 stuff thanks sampo!! --- Diffs of the changes: (+66 -4) IA64ISelPattern.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 66 insertions(+), 4 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.11 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.12 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.11 Mon Apr 4 00:05:52 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Wed Apr 6 04:55:17 2005 @@ -406,9 +406,6 @@ /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); -// bool isFoldableLoad(SDOperand Op); -// void EmitFoldedLoad(SDOperand Op, IA64AddressMode &AM); - unsigned SelectExpr(SDOperand N); void Select(SDOperand N); }; @@ -426,6 +423,37 @@ LoweredTokens.clear(); } +/// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It +/// returns zero when the input is not exactly a power of two. +static uint64_t ExactLog2(uint64_t Val) { + if (Val == 0 || (Val & (Val-1))) return 0; + unsigned Count = 0; + while (Val != 1) { + Val >>= 1; + ++Count; + } + return Count; +} + +/// ponderIntegerDivisionBy - When handling integer divides, if the divide +/// is by a constant such that we can efficiently codegen it, this +/// function says what to do. Currently, it returns 0 if the division must +/// become a genuine divide, and 1 if the division can be turned into a +/// right shift. +static unsigned ponderIntegerDivisionBy(SDOperand N, bool isSigned, + unsigned& Imm) { + if (N.getOpcode() != ISD::Constant) return 0; // if not a divide by + // a constant, give up. + + int64_t v = (int64_t)cast(N)->getSignExtended(); + + if ((Imm = ExactLog2(v))) { // if a division by a power of two, say so + return 1; + } + + return 0; // fallthrough +} + unsigned ISel::SelectExpr(SDOperand N) { unsigned Result; unsigned Tmp1, Tmp2, Tmp3; @@ -759,6 +787,16 @@ } case ISD::ADD: { + if(DestType == MVT::f64 && N.getOperand(0).getOpcode() == ISD::MUL && + N.getOperand(0).Val->hasOneUse()) { // if we can fold this add + // into an fma, do so: + // ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::FMA, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; // early exit + } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); if(DestType != MVT::f64) @@ -771,7 +809,9 @@ case ISD::MUL: { Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); - if(DestType != MVT::f64) { // integer multiply, emit some code (FIXME) + + if(DestType != MVT::f64) { // TODO: speed! + // boring old integer multiply with xma unsigned TempFR1=MakeReg(MVT::f64); unsigned TempFR2=MakeReg(MVT::f64); unsigned TempFR3=MakeReg(MVT::f64); @@ -787,6 +827,16 @@ } case ISD::SUB: { + if(DestType == MVT::f64 && N.getOperand(0).getOpcode() == ISD::MUL && + N.getOperand(0).Val->hasOneUse()) { // if we can fold this sub + // into an fms, do so: + // ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::FMS, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; // early exit + } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); if(DestType != MVT::f64) @@ -1015,6 +1065,18 @@ case ISD::UREM: isModulus=true; isSigned=false; break; } + if(!isModulus && !isFP) { // if this is an integer divide, + switch (ponderIntegerDivisionBy(N.getOperand(1), isSigned, Tmp3)) { + case 1: // division by a constant that's a power of 2 + Tmp1 = SelectExpr(N.getOperand(0)); + if(isSigned) // becomes a shift right: + BuildMI(BB, IA64::SHRS, 2, Result).addReg(Tmp1).addImm(Tmp3); + else + BuildMI(BB, IA64::SHRU, 2, Result).addReg(Tmp1).addImm(Tmp3); + return Result; // early exit + } + } + unsigned TmpPR=MakeReg(MVT::i1); // we need two scratch unsigned TmpPR2=MakeReg(MVT::i1); // predicate registers, unsigned TmpF1=MakeReg(MVT::f64); // and one metric truckload of FP regs. From lattner at cs.uiuc.edu Wed Apr 6 14:30:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 6 Apr 2005 14:30:00 -0500 Subject: [llvm-commits] CVS: llvm-poolalloc/lib/PoolAllocate/Makefile Message-ID: <200504061930.j36JU045013710@apoc.cs.uiuc.edu> Changes in directory llvm-poolalloc/lib/PoolAllocate: Makefile updated: 1.4 -> 1.5 --- Log message: Hopefully fix this on OS/X --- Diffs of the changes: (+1 -0) Makefile | 1 + 1 files changed, 1 insertion(+) Index: llvm-poolalloc/lib/PoolAllocate/Makefile diff -u llvm-poolalloc/lib/PoolAllocate/Makefile:1.4 llvm-poolalloc/lib/PoolAllocate/Makefile:1.5 --- llvm-poolalloc/lib/PoolAllocate/Makefile:1.4 Wed May 26 23:07:08 2004 +++ llvm-poolalloc/lib/PoolAllocate/Makefile Wed Apr 6 14:29:44 2005 @@ -7,6 +7,7 @@ # Give the name of a library. This will build a dynamic version. # SHARED_LIBRARY=1 +LOADABLE_MODULE = 1 DONT_BUILD_RELINKED=1 LIBRARYNAME=poolalloc From lattner at cs.uiuc.edu Wed Apr 6 14:46:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 6 Apr 2005 14:46:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/ModuloScheduling/DependenceAnalyzer.cpp Message-ID: <200504061946.j36Jk2Td013955@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/ModuloScheduling: DependenceAnalyzer.cpp updated: 1.2 -> 1.3 --- Log message: Fix a namespace issue, reported by Vladimir Merzliakov! --- Diffs of the changes: (+4 -5) DependenceAnalyzer.cpp | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) Index: llvm/lib/Target/SparcV9/ModuloScheduling/DependenceAnalyzer.cpp diff -u llvm/lib/Target/SparcV9/ModuloScheduling/DependenceAnalyzer.cpp:1.2 llvm/lib/Target/SparcV9/ModuloScheduling/DependenceAnalyzer.cpp:1.3 --- llvm/lib/Target/SparcV9/ModuloScheduling/DependenceAnalyzer.cpp:1.2 Fri Apr 1 09:41:30 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/DependenceAnalyzer.cpp Wed Apr 6 14:45:39 2005 @@ -16,15 +16,16 @@ #include "DependenceAnalyzer.h" #include "llvm/Type.h" #include "llvm/Support/Debug.h" - -namespace llvm { +using namespace llvm; /// Create ModuloSchedulingPass /// -FunctionPass *llvm::createDependenceAnalyzer() { +namespace llvm { +FunctionPass *createDependenceAnalyzer() { return new DependenceAnalyzer(); } +} bool DependenceAnalyzer::runOnFunction(Function &F) { AA = &getAnalysis(); @@ -105,6 +106,4 @@ DependenceResult dr = DependenceResult(deps); return dr; } -} - From alenhar2 at cs.uiuc.edu Wed Apr 6 15:25:58 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 6 Apr 2005 15:25:58 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504062025.j36KPwtM014233@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.80 -> 1.81 --- Log message: Added Nate's div by constant stuff, also scaled operations! --- Diffs of the changes: (+252 -21) AlphaISelPattern.cpp | 273 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 252 insertions(+), 21 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.80 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.81 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.80 Tue Apr 5 15:51:46 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Wed Apr 6 15:25:34 2005 @@ -58,25 +58,29 @@ addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass); addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass); - setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote); - setOperationAction(ISD::EXTLOAD , MVT::f32 , Promote); + setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote); + setOperationAction(ISD::EXTLOAD , MVT::f32 , Promote); - setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand); - setOperationAction(ISD::ZEXTLOAD , MVT::i32 , Expand); + setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand); + setOperationAction(ISD::ZEXTLOAD , MVT::i32 , Expand); - setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); - setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand); - setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand); - - setOperationAction(ISD::SREM , MVT::f32 , Expand); - setOperationAction(ISD::SREM , MVT::f64 , Expand); - - setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); - setOperationAction(ISD::MEMSET , MVT::Other, Expand); - setOperationAction(ISD::MEMCPY , MVT::Other, Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand); + + setOperationAction(ISD::SREM , MVT::f32 , Expand); + setOperationAction(ISD::SREM , MVT::f64 , Expand); + + //If this didn't legalize into a div.... + // setOperationAction(ISD::SREM , MVT::i64, Expand); + // setOperationAction(ISD::UREM , MVT::i64, Expand); + + setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); + setOperationAction(ISD::MEMSET , MVT::Other, Expand); + setOperationAction(ISD::MEMCPY , MVT::Other, Expand); //Doesn't work yet - setOperationAction(ISD::SETCC , MVT::f32, Promote); + setOperationAction(ISD::SETCC , MVT::f32, Promote); computeRegisterProperties(); @@ -335,7 +339,10 @@ /// Alpha-specific SelectionDAG. AlphaTargetLowering AlphaLowering; - + SelectionDAG *ISelDAG; // Hack to support us having a dag->dag transform + // for sdiv and udiv until it is put into the future + // dag combiner. + /// ExprMap - As shared expressions are codegen'd, we keep track of which /// vreg the value is produced in, so we only emit one copy of each compiled /// tree. @@ -354,6 +361,7 @@ virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { DEBUG(BB->dump()); // Codegen the basic block. + ISelDAG = &DAG; Select(DAG.getRoot()); // Clear state used for selection. @@ -371,9 +379,162 @@ void MoveInt2FP(unsigned src, unsigned dst, bool isDouble); //returns whether the sense of the comparison was inverted bool SelectFPSetCC(SDOperand N, unsigned dst); + + // dag -> dag expanders for integer divide by constant + SDOperand BuildSDIVSequence(SDOperand N); + SDOperand BuildUDIVSequence(SDOperand N); + }; } +//Shamelessly adapted from PPC32 +// Structure used to return the necessary information to codegen an SDIV as +// a multiply. +struct ms { + int64_t m; // magic number + int64_t s; // shift amount +}; + +struct mu { + uint64_t m; // magic number + int64_t a; // add indicator + int64_t s; // shift amount +}; + +/// magic - calculate the magic numbers required to codegen an integer sdiv as +/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, +/// or -1. +static struct ms magic(int64_t d) { + int64_t p; + uint64_t ad, anc, delta, q1, r1, q2, r2, t; + const uint64_t two63 = 9223372036854775808ULL; // 2^63 + struct ms mag; + + ad = abs(d); + t = two63 + ((uint64_t)d >> 63); + anc = t - 1 - t%ad; // absolute value of nc + p = 31; // initialize p + q1 = two63/anc; // initialize q1 = 2p/abs(nc) + r1 = two63 - q1*anc; // initialize r1 = rem(2p,abs(nc)) + q2 = two63/ad; // initialize q2 = 2p/abs(d) + r2 = two63 - q2*ad; // initialize r2 = rem(2p,abs(d)) + do { + p = p + 1; + q1 = 2*q1; // update q1 = 2p/abs(nc) + r1 = 2*r1; // update r1 = rem(2p/abs(nc)) + if (r1 >= anc) { // must be unsigned comparison + q1 = q1 + 1; + r1 = r1 - anc; + } + q2 = 2*q2; // update q2 = 2p/abs(d) + r2 = 2*r2; // update r2 = rem(2p/abs(d)) + if (r2 >= ad) { // must be unsigned comparison + q2 = q2 + 1; + r2 = r2 - ad; + } + delta = ad - r2; + } while (q1 < delta || (q1 == delta && r1 == 0)); + + mag.m = q2 + 1; + if (d < 0) mag.m = -mag.m; // resulting magic number + mag.s = p - 64; // resulting shift + return mag; +} + +/// magicu - calculate the magic numbers required to codegen an integer udiv as +/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. +static struct mu magicu(uint64_t d) +{ + int64_t p; + uint64_t nc, delta, q1, r1, q2, r2; + struct mu magu; + magu.a = 0; // initialize "add" indicator + nc = - 1 - (-d)%d; + p = 31; // initialize p + q1 = 0x8000000000000000/nc; // initialize q1 = 2p/nc + r1 = 0x8000000000000000 - q1*nc; // initialize r1 = rem(2p,nc) + q2 = 0x7FFFFFFFFFFFFFFF/d; // initialize q2 = (2p-1)/d + r2 = 0x7FFFFFFFFFFFFFFF - q2*d; // initialize r2 = rem((2p-1),d) + do { + p = p + 1; + if (r1 >= nc - r1 ) { + q1 = 2*q1 + 1; // update q1 + r1 = 2*r1 - nc; // update r1 + } + else { + q1 = 2*q1; // update q1 + r1 = 2*r1; // update r1 + } + if (r2 + 1 >= d - r2) { + if (q2 >= 0x7FFFFFFFFFFFFFFF) magu.a = 1; + q2 = 2*q2 + 1; // update q2 + r2 = 2*r2 + 1 - d; // update r2 + } + else { + if (q2 >= 0x8000000000000000) magu.a = 1; + q2 = 2*q2; // update q2 + r2 = 2*r2 + 1; // update r2 + } + delta = d - 1 - r2; + } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); + magu.m = q2 + 1; // resulting magic number + magu.s = p - 32; // resulting shift + return magu; +} + +/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, +/// return a DAG expression to select that will generate the same value by +/// multiplying by a magic number. See: +/// +SDOperand ISel::BuildSDIVSequence(SDOperand N) { + int d = (int)cast(N.getOperand(1))->getSignExtended(); + ms magics = magic(d); + // Multiply the numerator (operand 0) by the magic value + SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i64, N.getOperand(0), + ISelDAG->getConstant(magics.m, MVT::i64)); + // If d > 0 and m < 0, add the numerator + if (d > 0 && magics.m < 0) + Q = ISelDAG->getNode(ISD::ADD, MVT::i64, Q, N.getOperand(0)); + // If d < 0 and m > 0, subtract the numerator. + if (d < 0 && magics.m > 0) + Q = ISelDAG->getNode(ISD::SUB, MVT::i64, Q, N.getOperand(0)); + // Shift right algebraic if shift value is nonzero + if (magics.s > 0) + Q = ISelDAG->getNode(ISD::SRA, MVT::i64, Q, + ISelDAG->getConstant(magics.s, MVT::i64)); + // Extract the sign bit and add it to the quotient + SDOperand T = + ISelDAG->getNode(ISD::SRL, MVT::i64, Q, ISelDAG->getConstant(63, MVT::i64)); + return ISelDAG->getNode(ISD::ADD, MVT::i64, Q, T); +} + +/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, +/// return a DAG expression to select that will generate the same value by +/// multiplying by a magic number. See: +/// +SDOperand ISel::BuildUDIVSequence(SDOperand N) { + unsigned d = + (unsigned)cast(N.getOperand(1))->getSignExtended(); + mu magics = magicu(d); + // Multiply the numerator (operand 0) by the magic value + SDOperand Q = ISelDAG->getNode(ISD::MULHU, MVT::i64, N.getOperand(0), + ISelDAG->getConstant(magics.m, MVT::i64)); + if (magics.a == 0) { + Q = ISelDAG->getNode(ISD::SRL, MVT::i64, Q, + ISelDAG->getConstant(magics.s, MVT::i64)); + } else { + SDOperand NPQ = ISelDAG->getNode(ISD::SUB, MVT::i64, N.getOperand(0), Q); + NPQ = ISelDAG->getNode(ISD::SRL, MVT::i64, NPQ, + ISelDAG->getConstant(1, MVT::i64)); + NPQ = ISelDAG->getNode(ISD::ADD, MVT::i64, NPQ, Q); + Q = ISelDAG->getNode(ISD::SRL, MVT::i64, NPQ, + ISelDAG->getConstant(magics.s-1, MVT::i64)); + } + return Q; +} + + + //These describe LDAx static const int IMM_LOW = -32768; static const int IMM_HIGH = 32767; @@ -959,7 +1120,26 @@ Node->dump(); assert(0 && "Node not handled!\n"); - + case ISD::MULHU: + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Alpha::UMULH, 2, Result).addReg(Tmp1).addReg(Tmp2); + case ISD::MULHS: + { + //MULHU - Ra<63>*Rb - Rb<63>*Ra + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + Tmp3 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::UMULH, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); + unsigned V1 = MakeReg(MVT::i64); + unsigned V2 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::CMOVGE, 3, V1).addReg(Tmp2).addReg(Alpha::R31).addReg(Tmp1); + BuildMI(BB, Alpha::CMOVGE, 3, V2).addReg(Tmp1).addReg(Alpha::R31).addReg(Tmp2); + unsigned IRes = MakeReg(MVT::i64); + BuildMI(BB, Alpha::SUBQ, 2, IRes).addReg(Tmp3).addReg(V1); + BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(IRes).addReg(V2); + return Result; + } case ISD::UNDEF: { BuildMI(BB, Alpha::IDEF, 0, Result); return Result; @@ -1517,8 +1697,43 @@ { bool isAdd = opcode == ISD::ADD; - //FIXME: first check for Scaled Adds and Subs! - if(N.getOperand(1).getOpcode() == ISD::Constant && + //first check for Scaled Adds and Subs! + //Valid for add and sub + if(N.getOperand(0).getOpcode() == ISD::SHL && + N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(0).getOperand(1))->getValue() == 2) + { + Tmp1 = SelectExpr(N.getOperand(1)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(0)); + BuildMI(BB, isAdd?Alpha::S4ADDQ:Alpha::S4SUBQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + } + else if(N.getOperand(0).getOpcode() == ISD::SHL && + N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(0).getOperand(1))->getValue() == 3) + { + Tmp1 = SelectExpr(N.getOperand(1)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(0)); + BuildMI(BB, isAdd?Alpha::S4ADDQ:Alpha::S8SUBQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + } + //Position prevents subs + else if(N.getOperand(1).getOpcode() == ISD::SHL && isAdd & + N.getOperand(1).getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1).getOperand(1))->getValue() == 2) + { + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1).getOperand(0)); + BuildMI(BB, Alpha::S8ADDQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + } + else if(N.getOperand(0).getOpcode() == ISD::SHL && isAdd && + N.getOperand(1).getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1).getOperand(1))->getValue() == 3) + { + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1).getOperand(0)); + BuildMI(BB, Alpha::S8ADDQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + } + //small addi + else if(N.getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(1))->getValue() <= 255) { //Normal imm add/sub Opc = isAdd ? Alpha::ADDQi : Alpha::SUBQi; @@ -1526,6 +1741,7 @@ Tmp2 = cast(N.getOperand(1))->getValue(); BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); } + //larger addi else if(N.getOperand(1).getOpcode() == ISD::Constant && (cast(N.getOperand(1))->getValue() <= 32767 || (long)cast(N.getOperand(1))->getValue() >= -32767)) @@ -1535,7 +1751,9 @@ if (!isAdd) Tmp2 = -Tmp2; BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1); - } else { + } + //give up and do the operation + else { //Normal add/sub Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ; Tmp1 = SelectExpr(N.getOperand(0)); @@ -1546,9 +1764,22 @@ } case ISD::SDIV: + case ISD::UDIV: + if (N.getOperand(1).getOpcode() == ISD::Constant && + ((int64_t)cast(N.getOperand(1))->getSignExtended() >= 2 || + (int64_t)cast(N.getOperand(1))->getSignExtended() <= -2)) + { + // If this is a divide by constant, we can emit code using some magic + // constants to implement it as a multiply instead. + ExprMap.erase(N); + if (opcode == ISD::SDIV) + return SelectExpr(BuildSDIVSequence(N)); + else + return SelectExpr(BuildUDIVSequence(N)); + } + //else fall though case ISD::UREM: case ISD::SREM: - case ISD::UDIV: //FIXME: alpha really doesn't support any of these operations, // the ops are expanded into special library calls with // special calling conventions From alenhar2 at cs.uiuc.edu Wed Apr 6 15:38:27 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 6 Apr 2005 15:38:27 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Alpha/ Message-ID: <200504062038.j36KcRac014314@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Alpha: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/test/Regression/CodeGen/Alpha added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From alenhar2 at cs.uiuc.edu Wed Apr 6 15:40:12 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 6 Apr 2005 15:40:12 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Alpha/s4addq.ll Message-ID: <200504062040.j36KeCUN014343@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Alpha: s4addq.ll added (r1.1) --- Log message: added first alpha codegen regression test --- Diffs of the changes: (+16 -0) s4addq.ll | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/test/Regression/CodeGen/Alpha/s4addq.ll diff -c /dev/null llvm/test/Regression/CodeGen/Alpha/s4addq.ll:1.1 *** /dev/null Wed Apr 6 15:39:31 2005 --- llvm/test/Regression/CodeGen/Alpha/s4addq.ll Wed Apr 6 15:39:17 2005 *************** *** 0 **** --- 1,16 ---- + ; Make sure this testcase codegens to the S4ADDQ instruction + ; RUN: llvm-as < %s | llc -march=alpha | grep 'S4ADDQ' + + target endian = little + target pointersize = 64 + target triple = "alphapca56-unknown-linux-gnu" + deplibs = [ "c", "crtend" ] + + implementation ; Functions: + + long %bar(long %x, long %y) { + entry: + %tmp.1 = shl long %x, ubyte 3 ; [#uses=1] + %tmp.3 = add long %tmp.1, %y ; [#uses=1] + ret long %tmp.3 + } From lattner at cs.uiuc.edu Wed Apr 6 15:55:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 6 Apr 2005 15:55:40 -0500 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Regression/C/2005-05-06-LongLongSignedShift.c Message-ID: <200504062055.j36KtesD014634@apoc.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Regression/C: 2005-05-06-LongLongSignedShift.c added (r1.1) --- Log message: new testcase that the PPC and X86 backends miscompile --- Diffs of the changes: (+5 -0) 2005-05-06-LongLongSignedShift.c | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm-test/SingleSource/Regression/C/2005-05-06-LongLongSignedShift.c diff -c /dev/null llvm-test/SingleSource/Regression/C/2005-05-06-LongLongSignedShift.c:1.1 *** /dev/null Wed Apr 6 15:55:34 2005 --- llvm-test/SingleSource/Regression/C/2005-05-06-LongLongSignedShift.c Wed Apr 6 15:55:24 2005 *************** *** 0 **** --- 1,5 ---- + int main(int argc, char **argv) { + printf("%lld\n", (argc-100LL) >> 38); + + return 0; + } From alenhar2 at cs.uiuc.edu Wed Apr 6 15:59:16 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 6 Apr 2005 15:59:16 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Alpha/s4addq.ll Message-ID: <200504062059.j36KxGJu016503@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Alpha: s4addq.ll updated: 1.1 -> 1.2 --- Log message: simplified --- Diffs of the changes: (+0 -5) s4addq.ll | 5 ----- 1 files changed, 5 deletions(-) Index: llvm/test/Regression/CodeGen/Alpha/s4addq.ll diff -u llvm/test/Regression/CodeGen/Alpha/s4addq.ll:1.1 llvm/test/Regression/CodeGen/Alpha/s4addq.ll:1.2 --- llvm/test/Regression/CodeGen/Alpha/s4addq.ll:1.1 Wed Apr 6 15:39:17 2005 +++ llvm/test/Regression/CodeGen/Alpha/s4addq.ll Wed Apr 6 15:59:03 2005 @@ -1,11 +1,6 @@ ; Make sure this testcase codegens to the S4ADDQ instruction ; RUN: llvm-as < %s | llc -march=alpha | grep 'S4ADDQ' -target endian = little -target pointersize = 64 -target triple = "alphapca56-unknown-linux-gnu" -deplibs = [ "c", "crtend" ] - implementation ; Functions: long %bar(long %x, long %y) { From lattner at cs.uiuc.edu Wed Apr 6 15:59:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 6 Apr 2005 15:59:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelSimple.cpp Message-ID: <200504062059.j36Kxn07016520@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelSimple.cpp updated: 1.310 -> 1.311 --- Log message: Fix SingleSource/Regression/C/2005-05-06-LongLongSignedShift.c, we were not properly sign extending the top of the result of a 64-bit shift right by a constant > 32. --- Diffs of the changes: (+5 -1) X86ISelSimple.cpp | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelSimple.cpp diff -u llvm/lib/Target/X86/X86ISelSimple.cpp:1.310 llvm/lib/Target/X86/X86ISelSimple.cpp:1.311 --- llvm/lib/Target/X86/X86ISelSimple.cpp:1.310 Thu Mar 24 11:32:10 2005 +++ llvm/lib/Target/X86/X86ISelSimple.cpp Wed Apr 6 15:59:35 2005 @@ -3074,7 +3074,11 @@ } else { BuildMI(*MBB, IP, isSigned ? X86::SAR32ri : X86::SHR32ri, 2, DestReg).addReg(SrcReg+1).addImm(Amount); - BuildMI(*MBB, IP, X86::MOV32ri, 1, DestReg+1).addImm(0); + if (isSigned) + BuildMI(*MBB, IP, X86::SAR32ri, 2, + DestReg+1).addReg(SrcReg+1).addImm(31); + else + BuildMI(*MBB, IP, X86::MOV32ri, 1, DestReg+1).addImm(0); } } } else { From alenhar2 at cs.uiuc.edu Wed Apr 6 16:00:13 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 6 Apr 2005 16:00:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504062100.j36L0DGM016545@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.81 -> 1.82 --- Log message: fix copy/paste errors, and add imm support to SxADDQ and SxSUBQ --- Diffs of the changes: (+32 -8) AlphaISelPattern.cpp | 40 ++++++++++++++++++++++++++++++++-------- 1 files changed, 32 insertions(+), 8 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.81 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.82 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.81 Wed Apr 6 15:25:34 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Wed Apr 6 15:59:59 2005 @@ -1703,34 +1703,58 @@ N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(0).getOperand(1))->getValue() == 2) { - Tmp1 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(0).getOperand(0)); - BuildMI(BB, isAdd?Alpha::S4ADDQ:Alpha::S4SUBQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + if (N.getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1))->getValue() <= 255) + BuildMI(BB, isAdd?Alpha::S4ADDQi:Alpha::S4SUBQi, 2, Result).addReg(Tmp2) + .addImm(cast(N.getOperand(1))->getValue()); + else { + Tmp1 = SelectExpr(N.getOperand(1)); + BuildMI(BB, isAdd?Alpha::S4ADDQ:Alpha::S4SUBQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + } } else if(N.getOperand(0).getOpcode() == ISD::SHL && N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(0).getOperand(1))->getValue() == 3) { - Tmp1 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(0).getOperand(0)); - BuildMI(BB, isAdd?Alpha::S4ADDQ:Alpha::S8SUBQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + if (N.getOperand(1).getOpcode() == ISD::Constant && + cast(N.getOperand(1))->getValue() <= 255) + BuildMI(BB, isAdd?Alpha::S8ADDQi:Alpha::S8SUBQi, 2, Result).addReg(Tmp2) + .addImm(cast(N.getOperand(1))->getValue()); + else { + Tmp1 = SelectExpr(N.getOperand(1)); + BuildMI(BB, isAdd?Alpha::S8ADDQ:Alpha::S8SUBQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + } } //Position prevents subs else if(N.getOperand(1).getOpcode() == ISD::SHL && isAdd & N.getOperand(1).getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(1).getOperand(1))->getValue() == 2) { - Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1).getOperand(0)); - BuildMI(BB, Alpha::S8ADDQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + if (N.getOperand(0).getOpcode() == ISD::Constant && + cast(N.getOperand(0))->getValue() <= 255) + BuildMI(BB, Alpha::S4ADDQi, 2, Result).addReg(Tmp2) + .addImm(cast(N.getOperand(0))->getValue()); + else { + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, Alpha::S4ADDQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + } } else if(N.getOperand(0).getOpcode() == ISD::SHL && isAdd && N.getOperand(1).getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(1).getOperand(1))->getValue() == 3) { - Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1).getOperand(0)); - BuildMI(BB, Alpha::S8ADDQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + if (N.getOperand(0).getOpcode() == ISD::Constant && + cast(N.getOperand(0))->getValue() <= 255) + BuildMI(BB, Alpha::S8ADDQi, 2, Result).addReg(Tmp2) + .addImm(cast(N.getOperand(0))->getValue()); + else { + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, Alpha::S8ADDQ, 2, Result).addReg(Tmp2).addReg(Tmp1); + } } //small addi else if(N.getOperand(1).getOpcode() == ISD::Constant && From natebegeman at mac.com Wed Apr 6 16:13:25 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 6 Apr 2005 16:13:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200504062113.QAA15654@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.74 -> 1.75 --- Log message: Teach ExpandShift how to handle shifts by a constant. This allows targets like PowerPC to codegen long shifts in many fewer instructions. --- Diffs of the changes: (+64 -8) LegalizeDAG.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 64 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.74 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.75 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.74 Tue Apr 5 19:23:54 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Apr 6 16:13:14 2005 @@ -1412,13 +1412,73 @@ /// low-parts expanded into Lo and Hi. bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDOperand Op,SDOperand Amt, SDOperand &Lo, SDOperand &Hi) { - // FIXME: This code is buggy, disable it for now. Note that we should at - // least handle the case when Amt is an immediate here. - return false; - assert((Opc == ISD::SHL || Opc == ISD::SRA || Opc == ISD::SRL) && "This is not a shift!"); + MVT::ValueType NVT = TLI.getTypeToTransformTo(Op.getValueType()); + SDOperand ShAmt = LegalizeOp(Amt); + MVT::ValueType ShTy = ShAmt.getValueType(); + unsigned VTBits = MVT::getSizeInBits(Op.getValueType()); + unsigned NVTBits = MVT::getSizeInBits(NVT); + + // Handle the case when Amt is an immediate. Other cases are currently broken + // and are disabled. + if (ConstantSDNode *CN = dyn_cast(Amt.Val)) { + unsigned Cst = CN->getValue(); + // Expand the incoming operand to be shifted, so that we have its parts + SDOperand InL, InH; + ExpandOp(Op, InL, InH); + switch(Opc) { + case ISD::SHL: + if (Cst > VTBits) { + Lo = DAG.getConstant(0, NVT); + Hi = DAG.getConstant(0, NVT); + } else if (Cst > NVTBits) { + Lo = DAG.getConstant(0, NVT); + Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Cst-NVTBits,ShTy)); + } else { + Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Cst, ShTy)); + Hi = DAG.getNode(ISD::OR, NVT, + DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(Cst, ShTy)), + DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(NVTBits-Cst, ShTy))); + } + return true; + case ISD::SRL: + if (Cst > VTBits) { + Lo = DAG.getConstant(0, NVT); + Hi = DAG.getConstant(0, NVT); + } else if (Cst > NVTBits) { + Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Cst-NVTBits,ShTy)); + Hi = DAG.getConstant(0, NVT); + } else { + Lo = DAG.getNode(ISD::OR, NVT, + DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(Cst, ShTy)), + DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(NVTBits-Cst, ShTy))); + Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Cst, ShTy)); + } + return true; + case ISD::SRA: + if (Cst > VTBits) { + Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH, + DAG.getConstant(NVTBits-1, ShTy)); + } else if (Cst > NVTBits) { + Lo = DAG.getNode(ISD::SRA, NVT, InH, + DAG.getConstant(Cst-NVTBits, ShTy)); + Hi = DAG.getNode(ISD::SRA, NVT, InH, + DAG.getConstant(NVTBits-1, ShTy)); + } else { + Lo = DAG.getNode(ISD::OR, NVT, + DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(Cst, ShTy)), + DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(NVTBits-Cst, ShTy))); + Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Cst, ShTy)); + } + return true; + } + } + // FIXME: The following code for expanding shifts using ISD::SELECT is buggy, + // so disable it for now. Currently targets are handling this via SHL_PARTS + // and friends. + return false; // If we have an efficient select operation (or if the selects will all fold // away), lower to some complex code, otherwise just emit the libcall. @@ -1428,10 +1488,6 @@ SDOperand InL, InH; ExpandOp(Op, InL, InH); - SDOperand ShAmt = LegalizeOp(Amt); - MVT::ValueType ShTy = ShAmt.getValueType(); - - unsigned NVTBits = MVT::getSizeInBits(NVT); SDOperand NAmt = DAG.getNode(ISD::SUB, ShTy, // NAmt = 32-ShAmt DAG.getConstant(NVTBits, ShTy), ShAmt); From lattner at cs.uiuc.edu Wed Apr 6 16:45:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 6 Apr 2005 16:45:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp Message-ID: <200504062145.j36LjG99020592@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolution.cpp updated: 1.36 -> 1.37 --- Log message: Don't make this require loopsimplify. It works BETTER with loop simplify but should not require it. --- Diffs of the changes: (+0 -1) ScalarEvolution.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.36 llvm/lib/Analysis/ScalarEvolution.cpp:1.37 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.36 Tue Mar 8 23:34:41 2005 +++ llvm/lib/Analysis/ScalarEvolution.cpp Wed Apr 6 16:45:00 2005 @@ -2320,7 +2320,6 @@ void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); - AU.addRequiredID(LoopSimplifyID); AU.addRequiredTransitive(); } From alenhar2 at cs.uiuc.edu Wed Apr 6 17:03:27 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 6 Apr 2005 17:03:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504062203.j36M3RSF020753@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.82 -> 1.83 --- Log message: added sdiv by 2^k and works for neg divisors also --- Diffs of the changes: (+59 -10) AlphaISelPattern.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 59 insertions(+), 10 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.82 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.83 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.82 Wed Apr 6 15:59:59 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Wed Apr 6 17:03:13 2005 @@ -533,6 +533,18 @@ return Q; } +//From PPC32 +/// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It +/// returns zero when the input is not exactly a power of two. +static unsigned ExactLog2(uint64_t Val) { + if (Val == 0 || (Val & (Val-1))) return 0; + unsigned Count = 0; + while (Val != 1) { + Val >>= 1; + ++Count; + } + return Count; +} //These describe LDAx @@ -1788,18 +1800,55 @@ } case ISD::SDIV: + { + ConstantSDNode* CSD; + //check if we can convert into a shift! + if ((CSD = dyn_cast(N.getOperand(1).Val)) && + (int64_t)CSD->getSignExtended() != 0 && + ExactLog2(abs((int64_t)CSD->getSignExtended())) != 0) + { + unsigned k = ExactLog2(abs(CSD->getSignExtended())); + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = MakeReg(MVT::i64); + if (k == 1) + Tmp2 = Tmp1; + else + { + Tmp2 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::SRAi, 2, Tmp2).addReg(Tmp1).addImm(k - 1); + } + Tmp3 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::SRLi, 2, Tmp3).addReg(Tmp2).addImm(64-k); + unsigned Tmp4 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::ADDQ, 2, Tmp4).addReg(Tmp3).addReg(Tmp1); + if ((int64_t)CSD->getSignExtended() > 0) + BuildMI(BB, Alpha::SRAi, 2, Result).addReg(Tmp4).addImm(k); + else + { + unsigned Tmp5 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::SRAi, 2, Tmp5).addReg(Tmp4).addImm(k); + BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::R31).addReg(Tmp5); + } + return Result; + } + } + //Else fall through + case ISD::UDIV: - if (N.getOperand(1).getOpcode() == ISD::Constant && - ((int64_t)cast(N.getOperand(1))->getSignExtended() >= 2 || - (int64_t)cast(N.getOperand(1))->getSignExtended() <= -2)) { - // If this is a divide by constant, we can emit code using some magic - // constants to implement it as a multiply instead. - ExprMap.erase(N); - if (opcode == ISD::SDIV) - return SelectExpr(BuildSDIVSequence(N)); - else - return SelectExpr(BuildUDIVSequence(N)); + ConstantSDNode* CSD; + if ((CSD = dyn_cast(N.getOperand(1).Val)) && + ((int64_t)CSD->getSignExtended() >= 2 || + (int64_t)CSD->getSignExtended() <= -2)) + { + // If this is a divide by constant, we can emit code using some magic + // constants to implement it as a multiply instead. + ExprMap.erase(N); + if (opcode == ISD::SDIV) + return SelectExpr(BuildSDIVSequence(N)); + else + return SelectExpr(BuildUDIVSequence(N)); + } } //else fall though case ISD::UREM: From alkis at cs.uiuc.edu Wed Apr 6 17:09:51 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 6 Apr 2005 17:09:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504062209.RAA16072@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.83 -> 1.84 --- Log message: Make these 64 bit constants so that this compiles on x86-32 as well. --- Diffs of the changes: (+6 -6) AlphaISelPattern.cpp | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.83 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.84 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.83 Wed Apr 6 17:03:13 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Wed Apr 6 17:09:40 2005 @@ -451,10 +451,10 @@ magu.a = 0; // initialize "add" indicator nc = - 1 - (-d)%d; p = 31; // initialize p - q1 = 0x8000000000000000/nc; // initialize q1 = 2p/nc - r1 = 0x8000000000000000 - q1*nc; // initialize r1 = rem(2p,nc) - q2 = 0x7FFFFFFFFFFFFFFF/d; // initialize q2 = (2p-1)/d - r2 = 0x7FFFFFFFFFFFFFFF - q2*d; // initialize r2 = rem((2p-1),d) + q1 = 0x8000000000000000ll/nc; // initialize q1 = 2p/nc + r1 = 0x8000000000000000ll - q1*nc; // initialize r1 = rem(2p,nc) + q2 = 0x7FFFFFFFFFFFFFFFll/d; // initialize q2 = (2p-1)/d + r2 = 0x7FFFFFFFFFFFFFFFll - q2*d; // initialize r2 = rem((2p-1),d) do { p = p + 1; if (r1 >= nc - r1 ) { @@ -466,12 +466,12 @@ r1 = 2*r1; // update r1 } if (r2 + 1 >= d - r2) { - if (q2 >= 0x7FFFFFFFFFFFFFFF) magu.a = 1; + if (q2 >= 0x7FFFFFFFFFFFFFFFll) magu.a = 1; q2 = 2*q2 + 1; // update q2 r2 = 2*r2 + 1 - d; // update r2 } else { - if (q2 >= 0x8000000000000000) magu.a = 1; + if (q2 >= 0x8000000000000000ll) magu.a = 1; q2 = 2*q2; // update q2 r2 = 2*r2 + 1; // update r2 } From natebegeman at mac.com Wed Apr 6 17:42:19 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 6 Apr 2005 17:42:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Message-ID: <200504062242.RAA16224@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelSimple.cpp updated: 1.133 -> 1.134 --- Log message: Fix some shift bugs --- Diffs of the changes: (+12 -3) PPC32ISelSimple.cpp | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.133 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.134 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.133 Mon Apr 4 23:22:58 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Wed Apr 6 17:42:08 2005 @@ -2779,8 +2779,13 @@ .addImm(32-Amount).addImm(Amount).addImm(31); BuildMI(*MBB, IP, PPC::RLWIMI, 5, DestReg+1).addReg(TempReg) .addReg(SrcReg).addImm(32-Amount).addImm(0).addImm(Amount-1); - BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(SrcReg) - .addImm(32-Amount).addImm(Amount).addImm(31); + if (isSigned) { + BuildMI(*MBB, IP, PPC::SRAWI, 2, DestReg).addReg(SrcReg) + .addImm(Amount); + } else { + BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(SrcReg) + .addImm(32-Amount).addImm(Amount).addImm(31); + } } } else { // Shifting more than 32 bits Amount -= 32; @@ -2805,7 +2810,11 @@ BuildMI(*MBB, IP, PPC::OR, 2, DestReg+1).addReg(SrcReg) .addReg(SrcReg); } - BuildMI(*MBB, IP,PPC::LI, 1, DestReg).addSImm(0); + if (isSigned) + BuildMI(*MBB, IP, PPC::SRAWI, 2, DestReg).addReg(SrcReg) + .addImm(31); + else + BuildMI(*MBB, IP,PPC::LI, 1, DestReg).addSImm(0); } } } else { From natebegeman at mac.com Wed Apr 6 18:51:51 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 6 Apr 2005 18:51:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504062351.SAA16669@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.49 -> 1.50 --- Log message: Pattern match bitfield insert, which helps shift long by immediate, among other things. --- Diffs of the changes: (+152 -15) PPC32ISelPattern.cpp | 167 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 152 insertions(+), 15 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.49 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.50 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.49 Wed Apr 6 01:44:57 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Wed Apr 6 18:51:40 2005 @@ -489,6 +489,7 @@ unsigned getGlobalBaseReg(); unsigned getConstDouble(double floatVal, unsigned Result); + bool SelectBitfieldInsert(SDOperand OR, unsigned Result); unsigned SelectSetCR0(SDOperand CC); unsigned SelectExpr(SDOperand N); unsigned SelectExprFP(SDOperand N, unsigned Result); @@ -510,6 +511,61 @@ return Count; } +// IsRunOfOnes - returns true if Val consists of one contiguous run of 1's with +// any number of 0's on either side. the 1's are allowed to wrap from LSB to +// MSB. so 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs. 0x0F0F0000 is +// not, since all 1's are not contiguous. +static bool IsRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) { + bool isRun = true; + MB = 0; + ME = 0; + + // look for first set bit + int i = 0; + for (; i < 32; i++) { + if ((Val & (1 << (31 - i))) != 0) { + MB = i; + ME = i; + break; + } + } + + // look for last set bit + for (; i < 32; i++) { + if ((Val & (1 << (31 - i))) == 0) + break; + ME = i; + } + + // look for next set bit + for (; i < 32; i++) { + if ((Val & (1 << (31 - i))) != 0) + break; + } + + // if we exhausted all the bits, we found a match at this point for 0*1*0* + if (i == 32) + return true; + + // since we just encountered more 1's, if it doesn't wrap around to the + // most significant bit of the word, then we did not find a match to 1*0*1* so + // exit. + if (MB != 0) + return false; + + // look for last set bit + for (MB = i; i < 32; i++) { + if ((Val & (1 << (31 - i))) == 0) + break; + } + + // if we exhausted all the bits, then we found a match for 1*0*1*, otherwise, + // the value is not a run of ones. + if (i == 32) + return true; + return false; +} + /// getImmediateForOpcode - This method returns a value indicating whether /// the ConstantSDNode N can be used as an immediate to Opcode. The return /// values are either 0, 1 or 2. 0 indicates that either N is not a @@ -769,6 +825,78 @@ return Result; } +/// SelectBitfieldInsert - turn an or of two masked values into +/// the rotate left word immediate then mask insert (rlwimi) instruction. +/// Returns true on success, false if the caller still needs to select OR. +/// +/// Patterns matched: +/// 1. or shl, and 5. or and, and +/// 2. or and, shl 6. or shl, shr +/// 3. or shr, and 7. or shr, shl +/// 4. or and, shr +bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) { + unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, Amount = 0; + unsigned Op0Opc = OR.getOperand(0).getOpcode(); + unsigned Op1Opc = OR.getOperand(1).getOpcode(); + + // Verify that we have the correct opcodes + if (ISD::SHL != Op0Opc && ISD::SRL != Op0Opc && ISD::AND != Op0Opc) + return false; + if (ISD::SHL != Op1Opc && ISD::SRL != Op1Opc && ISD::AND != Op1Opc) + return false; + + // Generate Mask value for Target + if (ConstantSDNode *CN = + dyn_cast(OR.getOperand(0).getOperand(1).Val)) { + switch(Op0Opc) { + case ISD::SHL: TgtMask <<= (unsigned)CN->getValue(); break; + case ISD::SRL: TgtMask >>= (unsigned)CN->getValue(); break; + case ISD::AND: TgtMask &= (unsigned)CN->getValue(); break; + } + } else { + return false; + } + + // Generate Mask value for Insert + if (ConstantSDNode *CN = + dyn_cast(OR.getOperand(1).getOperand(1).Val)) { + switch(Op1Opc) { + case ISD::SHL: + Amount = CN->getValue(); + InsMask <<= Amount; + break; + case ISD::SRL: + Amount = CN->getValue(); + InsMask >>= Amount; + Amount = 32-Amount; + break; + case ISD::AND: + InsMask &= (unsigned)CN->getValue(); + break; + } + } else { + return false; + } + + // Verify that the Target mask and Insert mask together form a full word mask + // and that the Insert mask is a run of set bits (which implies both are runs + // of set bits). Given that, Select the arguments and generate the rlwimi + // instruction. + unsigned MB, ME; + if (((TgtMask ^ InsMask) == 0xFFFFFFFF) && IsRunOfOnes(InsMask, MB, ME)) { + unsigned Tmp1, Tmp2; + if (Op0Opc == ISD::AND) + Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0)); + else + Tmp1 = SelectExpr(OR.getOperand(0)); + Tmp2 = SelectExpr(OR.getOperand(1).getOperand(0)); + BuildMI(BB, PPC::RLWIMI, 5, Result).addReg(Tmp1).addReg(Tmp2) + .addImm(Amount).addImm(MB).addImm(ME); + return true; + } + return false; +} + unsigned ISel::SelectSetCR0(SDOperand CC) { unsigned Opc, Tmp1, Tmp2; static const unsigned CompareOpcodes[] = @@ -1476,31 +1604,40 @@ return Result; case ISD::AND: + Tmp1 = SelectExpr(N.getOperand(0)); + // FIXME: should add check in getImmediateForOpcode to return a value + // indicating the immediate is a run of set bits so we can emit a bitfield + // clear with RLWINM instead. + switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { + default: assert(0 && "unhandled result code"); + case 0: // No immediate + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::AND, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case 1: // Low immediate + BuildMI(BB, PPC::ANDIo, 2, Result).addReg(Tmp1).addImm(Tmp2); + break; + case 2: // Shifted immediate + BuildMI(BB, PPC::ANDISo, 2, Result).addReg(Tmp1).addImm(Tmp2); + break; + } + return Result; + case ISD::OR: + if (SelectBitfieldInsert(N, Result)) + return Result; Tmp1 = SelectExpr(N.getOperand(0)); switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { default: assert(0 && "unhandled result code"); case 0: // No immediate Tmp2 = SelectExpr(N.getOperand(1)); - switch (opcode) { - case ISD::AND: Opc = PPC::AND; break; - case ISD::OR: Opc = PPC::OR; break; - } - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp2); break; case 1: // Low immediate - switch (opcode) { - case ISD::AND: Opc = PPC::ANDIo; break; - case ISD::OR: Opc = PPC::ORI; break; - } - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); + BuildMI(BB, PPC::ORI, 2, Result).addReg(Tmp1).addImm(Tmp2); break; case 2: // Shifted immediate - switch (opcode) { - case ISD::AND: Opc = PPC::ANDISo; break; - case ISD::OR: Opc = PPC::ORIS; break; - } - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); + BuildMI(BB, PPC::ORIS, 2, Result).addReg(Tmp1).addImm(Tmp2); break; } return Result; From lattner at cs.uiuc.edu Wed Apr 6 19:30:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 6 Apr 2005 19:30:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504070030.j370UTjw022795@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.59 -> 1.60 --- Log message: Fix a really scary bug that Nate found where we weren't deleting the right elements auto of the autoCSE maps. --- Diffs of the changes: (+1 -1) SelectionDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.59 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.60 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.59 Tue Apr 5 17:36:56 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Apr 6 19:30:13 2005 @@ -241,7 +241,7 @@ case ISD::SEXTLOAD: case ISD::ZEXTLOAD: { EVTStruct NN; - NN.Opcode = ISD::TRUNCSTORE; + NN.Opcode = N->getOpcode(); NN.VT = N->getValueType(0); NN.EVT = cast(N)->getExtraValueType(); for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) From duraid at octopus.com.au Thu Apr 7 07:32:35 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Thu, 7 Apr 2005 07:32:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64InstrInfo.td Message-ID: <200504071232.HAA14117@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64InstrInfo.td updated: 1.6 -> 1.7 --- Log message: add immediate forms of add, sub, shift --- Diffs of the changes: (+14 -0) IA64InstrInfo.td | 14 ++++++++++++++ 1 files changed, 14 insertions(+) Index: llvm/lib/Target/IA64/IA64InstrInfo.td diff -u llvm/lib/Target/IA64/IA64InstrInfo.td:1.6 llvm/lib/Target/IA64/IA64InstrInfo.td:1.7 --- llvm/lib/Target/IA64/IA64InstrInfo.td:1.6 Wed Apr 6 04:54:09 2005 +++ llvm/lib/Target/IA64/IA64InstrInfo.td Thu Apr 7 07:32:24 2005 @@ -16,6 +16,12 @@ include "IA64InstrFormats.td" def u6imm : Operand; +def s8imm : Operand { + let PrintMethod = "printS8ImmOperand"; +} +def s14imm : Operand { + let PrintMethod = "printS14ImmOperand"; +} def s16imm : Operand; def s21imm : Operand { let PrintMethod = "printS21ImmOperand"; @@ -107,8 +113,12 @@ "shl $dst = $src1, $imm;;">; // FIXME: 6 immediate bits, not 21 def SHRU : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "shr.u $dst = $src1, $src2;;">; +def SHRUI : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s21imm:$imm), + "shr.u $dst = $src1, $imm;;">; def SHRS : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "shr $dst = $src1, $src2;;">; +def SHRSI : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s21imm:$imm), + "shr $dst = $src1, $imm;;">; def DEPZ : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm1, u6imm:$imm2), "dep.z $dst = $src1, $imm1, $imm2;;">; @@ -177,6 +187,8 @@ def ADD : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "add $dst = $src1, $src2;;">; +def ADDIMM14 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s14imm:$imm), + "adds $dst = $imm, $src1;;">; def ADDIMM22 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s21imm:$imm), "add $dst = $imm, $src1;;">; @@ -194,6 +206,8 @@ def SUB : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), "sub $dst = $src1, $src2;;">; +def SUBIMM8 : AForm<0x03, 0x0b, (ops GR:$dst, s8imm:$imm, GR:$src2), + "sub $dst = $imm, $src2;;">; def ST1 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), "st1 [$dstPtr] = $value;;">; From duraid at octopus.com.au Thu Apr 7 07:33:49 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Thu, 7 Apr 2005 07:33:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200504071233.HAA14129@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.12 -> 1.13 --- Log message: codegen immediate forms of add/sub/shift --- Diffs of the changes: (+66 -13) IA64ISelPattern.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 66 insertions(+), 13 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.12 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.13 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.12 Wed Apr 6 04:55:17 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Thu Apr 7 07:33:38 2005 @@ -454,6 +454,30 @@ return 0; // fallthrough } +static unsigned ponderIntegerAdditionWith(SDOperand N, unsigned& Imm) { + if (N.getOpcode() != ISD::Constant) return 0; // if not adding a + // constant, give up. + int64_t v = (int64_t)cast(N)->getSignExtended(); + + if (v <= 8191 && v >= -8192) { // if this constants fits in 14 bits, say so + Imm = v & 0x3FFF; // 14 bits + return 1; + } + return 0; // fallthrough +} + +static unsigned ponderIntegerSubtractionFrom(SDOperand N, unsigned& Imm) { + if (N.getOpcode() != ISD::Constant) return 0; // if not subtracting a + // constant, give up. + int64_t v = (int64_t)cast(N)->getSignExtended(); + + if (v <= 127 && v >= -128) { // if this constants fits in 8 bits, say so + Imm = v & 0xFF; // 8 bits + return 1; + } + return 0; // fallthrough +} + unsigned ISel::SelectExpr(SDOperand N) { unsigned Result; unsigned Tmp1, Tmp2, Tmp3; @@ -799,10 +823,16 @@ } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); - if(DestType != MVT::f64) - BuildMI(BB, IA64::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); // int - else - BuildMI(BB, IA64::FADD, 2, Result).addReg(Tmp1).addReg(Tmp2); // FP + if(DestType != MVT::f64) { // integer addition: + switch (ponderIntegerAdditionWith(N.getOperand(1), Tmp3)) { + case 1: // adding a constant that's 14 bits + BuildMI(BB, IA64::ADDIMM14, 2, Result).addReg(Tmp1).addSImm(Tmp3); + return Result; // early exit + } // fallthrough and emit a reg+reg ADD: + BuildMI(BB, IA64::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); + } else { // this is a floating point addition + BuildMI(BB, IA64::FADD, 2, Result).addReg(Tmp1).addReg(Tmp2); + } return Result; } @@ -839,10 +869,16 @@ } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); - if(DestType != MVT::f64) - BuildMI(BB, IA64::SUB, 2, Result).addReg(Tmp1).addReg(Tmp2); - else + if(DestType != MVT::f64) { // integer subtraction: + switch (ponderIntegerSubtractionFrom(N.getOperand(0), Tmp3)) { + case 1: // subtracting *from* an 8 bit constant: + BuildMI(BB, IA64::SUBIMM8, 2, Result).addSImm(Tmp3).addReg(Tmp2); + return Result; // early exit + } // fallthrough and emit a reg+reg SUB: + BuildMI(BB, IA64::SUB, 2, Result).addReg(Tmp1).addReg(Tmp2); + } else { // this is a floating point subtraction BuildMI(BB, IA64::FSUB, 2, Result).addReg(Tmp1).addReg(Tmp2); + } return Result; } @@ -1025,20 +1061,37 @@ case ISD::SHL: { Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, IA64::SHL, 2, Result).addReg(Tmp1).addReg(Tmp2); + if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { + Tmp2 = CN->getValue(); + BuildMI(BB, IA64::SHLI, 2, Result).addReg(Tmp1).addImm(Tmp2); + } else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::SHL, 2, Result).addReg(Tmp1).addReg(Tmp2); + } return Result; } + case ISD::SRL: { Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, IA64::SHRU, 2, Result).addReg(Tmp1).addReg(Tmp2); + if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { + Tmp2 = CN->getValue(); + BuildMI(BB, IA64::SHRUI, 2, Result).addReg(Tmp1).addImm(Tmp2); + } else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::SHRU, 2, Result).addReg(Tmp1).addReg(Tmp2); + } return Result; } + case ISD::SRA: { Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, IA64::SHRS, 2, Result).addReg(Tmp1).addReg(Tmp2); + if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { + Tmp2 = CN->getValue(); + BuildMI(BB, IA64::SHRSI, 2, Result).addReg(Tmp1).addImm(Tmp2); + } else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, IA64::SHRS, 2, Result).addReg(Tmp1).addReg(Tmp2); + } return Result; } From duraid at octopus.com.au Thu Apr 7 07:34:46 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Thu, 7 Apr 2005 07:34:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64AsmPrinter.cpp Message-ID: <200504071234.HAA14141@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64AsmPrinter.cpp updated: 1.7 -> 1.8 --- Log message: teach asmprinter to print s8/s14 operands --- Diffs of the changes: (+12 -0) IA64AsmPrinter.cpp | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/lib/Target/IA64/IA64AsmPrinter.cpp diff -u llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.7 llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.8 --- llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.7 Sun Apr 3 09:52:01 2005 +++ llvm/lib/Target/IA64/IA64AsmPrinter.cpp Thu Apr 7 07:34:36 2005 @@ -233,6 +233,18 @@ MVT::ValueType VT) { O << (unsigned short)MI->getOperand(OpNo).getImmedValue(); } + void printS8ImmOperand(const MachineInstr *MI, unsigned OpNo, + MVT::ValueType VT) { + int val=(unsigned int)MI->getOperand(OpNo).getImmedValue(); + if(val>=128) val=val-256; // if negative, flip sign + O << val; + } + void printS14ImmOperand(const MachineInstr *MI, unsigned OpNo, + MVT::ValueType VT) { + int val=(unsigned int)MI->getOperand(OpNo).getImmedValue(); + if(val>=8192) val=val-16384; // if negative, flip sign + O << val; + } void printS21ImmOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { O << (int)MI->getOperand(OpNo).getImmedValue(); // FIXME (21, not 32!) From alenhar2 at cs.uiuc.edu Thu Apr 7 08:56:09 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 7 Apr 2005 08:56:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504071356.j37Du9Hm026736@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.84 -> 1.85 --- Log message: Yea, it wasn't happy --- Diffs of the changes: (+1 -0) AlphaISelPattern.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.84 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.85 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.84 Wed Apr 6 17:09:40 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Thu Apr 7 08:55:53 2005 @@ -1136,6 +1136,7 @@ Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); BuildMI(BB, Alpha::UMULH, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; case ISD::MULHS: { //MULHU - Ra<63>*Rb - Rb<63>*Ra From alenhar2 at cs.uiuc.edu Thu Apr 7 09:18:26 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 7 Apr 2005 09:18:26 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504071418.j37EIQmV026859@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.85 -> 1.86 --- Log message: It wasn't happy about this either --- Diffs of the changes: (+1 -1) AlphaISelPattern.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.85 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.86 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.85 Thu Apr 7 08:55:53 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Thu Apr 7 09:18:13 2005 @@ -1755,7 +1755,7 @@ BuildMI(BB, Alpha::S4ADDQ, 2, Result).addReg(Tmp2).addReg(Tmp1); } } - else if(N.getOperand(0).getOpcode() == ISD::SHL && isAdd && + else if(N.getOperand(1).getOpcode() == ISD::SHL && isAdd && N.getOperand(1).getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(1).getOperand(1))->getValue() == 3) { From lattner at cs.uiuc.edu Thu Apr 7 11:15:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 11:15:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200504071615.j37GFfuX031206@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.317 -> 1.318 --- Log message: Transform X-(X+Y) == -Y and X-(Y+X) == -Y --- Diffs of the changes: (+11 -2) InstructionCombining.cpp | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.317 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.318 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.317 Tue Mar 29 00:37:47 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Apr 7 11:15:25 2005 @@ -792,7 +792,15 @@ return NV; } - if (BinaryOperator *Op1I = dyn_cast(Op1)) + if (BinaryOperator *Op1I = dyn_cast(Op1)) { + if (Op1I->getOpcode() == Instruction::Add && + !Op0->getType()->isFloatingPoint()) { + if (Op1I->getOperand(0) == Op0) // X-(X+Y) == -Y + return BinaryOperator::createNeg(Op1I->getOperand(1), I.getName()); + else if (Op1I->getOperand(1) == Op0) // X-(Y+X) == -Y + return BinaryOperator::createNeg(Op1I->getOperand(0), I.getName()); + } + if (Op1I->hasOneUse()) { // Replace (x - (y - z)) with (x + (z - y)) if the (y - z) subexpression // is not used by anyone else... @@ -822,7 +830,7 @@ // -(X sdiv C) -> (X sdiv -C) if (Op1I->getOpcode() == Instruction::Div) if (ConstantSInt *CSI = dyn_cast(Op0)) - if (CSI->getValue() == 0) + if (CSI->isNullValue()) if (Constant *DivRHS = dyn_cast(Op1I->getOperand(1))) return BinaryOperator::createDiv(Op1I->getOperand(0), ConstantExpr::getNeg(DivRHS)); @@ -835,6 +843,7 @@ return BinaryOperator::createMul(Op0, CP1); } } + } if (BinaryOperator *Op0I = dyn_cast(Op0)) if (Op0I->getOpcode() == Instruction::Add) From lattner at cs.uiuc.edu Thu Apr 7 11:25:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 11:25:12 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/add.ll Message-ID: <200504071625.j37GPCpL032100@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: add.ll updated: 1.25 -> 1.26 --- Log message: new testcase --- Diffs of the changes: (+5 -0) add.ll | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/add.ll diff -u llvm/test/Regression/Transforms/InstCombine/add.ll:1.25 llvm/test/Regression/Transforms/InstCombine/add.ll:1.26 --- llvm/test/Regression/Transforms/InstCombine/add.ll:1.25 Wed Jan 19 15:48:31 2005 +++ llvm/test/Regression/Transforms/InstCombine/add.ll Thu Apr 7 11:24:59 2005 @@ -191,3 +191,8 @@ ret int %D } +int %test28(int %X) { + %Y = add int %X, 1234 + %Z = sub int 42, %Y + ret int %Z +} From lattner at cs.uiuc.edu Thu Apr 7 11:28:14 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 11:28:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200504071628.j37GSE4K032374@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.318 -> 1.319 --- Log message: Implement InstCombine/add.ll:test28, transforming C1-(X+C2) --> (C1-C2)-X. This occurs several dozen times in specint2k, particularly in crafty and gcc apparently. --- Diffs of the changes: (+8 -2) InstructionCombining.cpp | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.318 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.319 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.318 Thu Apr 7 11:15:25 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Apr 7 11:28:01 2005 @@ -795,10 +795,16 @@ if (BinaryOperator *Op1I = dyn_cast(Op1)) { if (Op1I->getOpcode() == Instruction::Add && !Op0->getType()->isFloatingPoint()) { - if (Op1I->getOperand(0) == Op0) // X-(X+Y) == -Y + if (Op1I->getOperand(0) == Op0) // X-(X+Y) == -Y return BinaryOperator::createNeg(Op1I->getOperand(1), I.getName()); - else if (Op1I->getOperand(1) == Op0) // X-(Y+X) == -Y + else if (Op1I->getOperand(1) == Op0) // X-(Y+X) == -Y return BinaryOperator::createNeg(Op1I->getOperand(0), I.getName()); + else if (ConstantInt *CI1 = dyn_cast(I.getOperand(0))) { + if (ConstantInt *CI2 = dyn_cast(Op1I->getOperand(1))) + // C1-(X+C2) --> (C1-C2)-X + return BinaryOperator::createSub(ConstantExpr::getSub(CI1, CI2), + Op1I->getOperand(0)); + } } if (Op1I->hasOneUse()) { From lattner at cs.uiuc.edu Thu Apr 7 11:41:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 11:41:58 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/sub.ll Message-ID: <200504071641.j37Gfw7k032642@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: sub.ll updated: 1.20 -> 1.21 --- Log message: new test --- Diffs of the changes: (+5 -0) sub.ll | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/sub.ll diff -u llvm/test/Regression/Transforms/InstCombine/sub.ll:1.20 llvm/test/Regression/Transforms/InstCombine/sub.ll:1.21 --- llvm/test/Regression/Transforms/InstCombine/sub.ll:1.20 Sat Nov 13 13:49:39 2004 +++ llvm/test/Regression/Transforms/InstCombine/sub.ll Thu Apr 7 11:41:45 2005 @@ -119,3 +119,8 @@ ret long %tmp.8 } +int %test19(int %X, int %Y) { + %Z = sub int %X, %Y + %Q = add int %Z, %Y + ret int %Q +} From lattner at cs.uiuc.edu Thu Apr 7 12:15:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 12:15:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200504071715.j37HF8cI001175@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.319 -> 1.320 --- Log message: Implement the following xforms: (X-Y)-X --> -Y A + (B - A) --> B (B - A) + A --> B --- Diffs of the changes: (+18 -3) InstructionCombining.cpp | 21 ++++++++++++++++++--- 1 files changed, 18 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.319 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.320 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.319 Thu Apr 7 11:28:01 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Apr 7 12:14:51 2005 @@ -629,6 +629,17 @@ // X + X --> X << 1 if (I.getType()->isInteger()) { if (Instruction *Result = AssociativeOpt(I, AddRHS(RHS))) return Result; + + if (Instruction *RHSI = dyn_cast(RHS)) { + if (RHSI->getOpcode() == Instruction::Sub) + if (LHS == RHSI->getOperand(1)) // A + (B - A) --> B + return ReplaceInstUsesWith(I, RHSI->getOperand(0)); + } + if (Instruction *LHSI = dyn_cast(LHS)) { + if (LHSI->getOpcode() == Instruction::Sub) + if (RHS == LHSI->getOperand(1)) // (B - A) + A --> B + return ReplaceInstUsesWith(I, LHSI->getOperand(0)); + } } // -A + B --> B - A @@ -640,6 +651,7 @@ if (Value *V = dyn_castNegVal(RHS)) return BinaryOperator::createSub(LHS, V); + ConstantInt *C2; if (Value *X = dyn_castFoldableMul(LHS, C2)) { if (X == RHS) // X*C + X --> X * (C+1) @@ -851,13 +863,16 @@ } } - if (BinaryOperator *Op0I = dyn_cast(Op0)) - if (Op0I->getOpcode() == Instruction::Add) - if (!Op0->getType()->isFloatingPoint()) { + if (!Op0->getType()->isFloatingPoint()) + if (BinaryOperator *Op0I = dyn_cast(Op0)) + if (Op0I->getOpcode() == Instruction::Add) { if (Op0I->getOperand(0) == Op1) // (Y+X)-Y == X return ReplaceInstUsesWith(I, Op0I->getOperand(1)); else if (Op0I->getOperand(1) == Op1) // (X+Y)-Y == X return ReplaceInstUsesWith(I, Op0I->getOperand(0)); + } else if (Op0I->getOpcode() == Instruction::Sub) { + if (Op0I->getOperand(0) == Op1) // (X-Y)-X == -Y + return BinaryOperator::createNeg(Op0I->getOperand(1), I.getName()); } ConstantInt *C1; From alenhar2 at cs.uiuc.edu Thu Apr 7 12:18:02 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 7 Apr 2005 12:18:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.td Message-ID: <200504071718.j37HI2Sv001216@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.td updated: 1.38 -> 1.39 --- Log message: lowercase instructions, makes diff happier --- Diffs of the changes: (+71 -71) AlphaInstrInfo.td | 142 +++++++++++++++++++++++++++--------------------------- 1 files changed, 71 insertions(+), 71 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.38 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.39 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.38 Sat Apr 2 16:32:39 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Thu Apr 7 12:17:48 2005 @@ -131,29 +131,29 @@ def CMOVEQi : OFormL< 0x11, 0x24, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), "cmoveq $RCOND,$L,$RDEST">; //CMOVE if RCOND = zero def CMOVGE : OForm< 0x11, 0x46, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "CMOVGE $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND >= zero + "cmovge $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND >= zero def CMOVGEi : OFormL< 0x11, 0x46, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "CMOVGE $RCOND,$L,$RDEST">; //CMOVE if RCOND >= zero + "cmovge $RCOND,$L,$RDEST">; //CMOVE if RCOND >= zero def CMOVGT : OForm< 0x11, 0x66, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "CMOVGT $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND > zero + "cmovgt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND > zero def CMOVGTi : OFormL< 0x11, 0x66, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "CMOVGT $RCOND,$L,$RDEST">; //CMOVE if RCOND > zero + "cmovgt $RCOND,$L,$RDEST">; //CMOVE if RCOND > zero def CMOVLBC : OForm< 0x11, 0x16, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "CMOVLBC $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit clear + "cmovlbc $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit clear def CMOVLBCi : OFormL< 0x11, 0x16, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "CMOVLBC $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit clear + "cmovlbc $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit clear def CMOVLBS : OForm< 0x11, 0x14, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "CMOVLBS $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit set + "cmovlbs $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit set def CMOVLBSi : OFormL< 0x11, 0x14, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "CMOVLBS $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit set + "cmovlbs $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit set def CMOVLE : OForm< 0x11, 0x64, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "CMOVLE $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND <= zero + "cmovle $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND <= zero def CMOVLEi : OFormL< 0x11, 0x64, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "CMOVLE $RCOND,$L,$RDEST">; //CMOVE if RCOND <= zero + "cmovle $RCOND,$L,$RDEST">; //CMOVE if RCOND <= zero def CMOVLT : OForm< 0x11, 0x44, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "CMOVLT $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND < zero + "cmovlt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND < zero def CMOVLTi : OFormL< 0x11, 0x44, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "CMOVLT $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero + "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero def CMOVNE : OForm< 0x11, 0x26, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), "cmovne $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND != zero def CMOVNEi : OFormL< 0x11, 0x26, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), @@ -180,10 +180,10 @@ def ADDQi : OFormL<0x10, 0x20, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "addq $RA,$L,$RC">; //Add quadword def AMASK : OForm< 0x11, 0x61, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "AMASK $RA,$RB,$RC">; //Architecture mask def AMASKi : OFormL<0x11, 0x61, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "AMASK $RA,$L,$RC">; //Architecture mask -def AND : OForm< 0x11, 0x00, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "AND $RA,$RB,$RC">; //Logical product -def ANDi : OFormL<0x11, 0x00, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "AND $RA,$L,$RC">; //Logical product -def BIC : OForm< 0x11, 0x08, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "BIC $RA,$RB,$RC">; //Bit clear -def BICi : OFormL<0x11, 0x08, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "BIC $RA,$L,$RC">; //Bit clear +def AND : OForm< 0x11, 0x00, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "and $RA,$RB,$RC">; //Logical product +def ANDi : OFormL<0x11, 0x00, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "and $RA,$L,$RC">; //Logical product +def BIC : OForm< 0x11, 0x08, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "bic $RA,$RB,$RC">; //Bit clear +def BICi : OFormL<0x11, 0x08, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "bic $RA,$L,$RC">; //Bit clear def BIS : OForm< 0x11, 0x20, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "bis $RA,$RB,$RC">; //Logical sum def BISi : OFormL<0x11, 0x20, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "bis $RA,$L,$RC">; //Logical sum def CTLZ : OForm< 0x1C, 0x32, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CTLZ $RA,$RB,$RC">; //Count leading zero @@ -192,8 +192,8 @@ def CTPOPi : OFormL<0x1C, 0x30, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "CTPOP $RA,$L,$RC">; //Count population def CTTZ : OForm< 0x1C, 0x33, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CTTZ $RA,$RB,$RC">; //Count trailing zero def CTTZi : OFormL<0x1C, 0x33, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "CTTZ $RA,$L,$RC">; //Count trailing zero -def EQV : OForm< 0x11, 0x48, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EQV $RA,$RB,$RC">; //Logical equivalence -def EQVi : OFormL<0x11, 0x48, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "EQV $RA,$L,$RC">; //Logical equivalence +def EQV : OForm< 0x11, 0x48, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "eqv $RA,$RB,$RC">; //Logical equivalence +def EQVi : OFormL<0x11, 0x48, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "eqv $RA,$L,$RC">; //Logical equivalence def EXTBL : OForm< 0x12, 0x06, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTBL $RA,$RB,$RC">; //Extract byte low def EXTBLi : OFormL<0x12, 0x06, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "EXTBL $RA,$L,$RC">; //Extract byte low def EXTLH : OForm< 0x12, 0x6A, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTLH $RA,$RB,$RC">; //Extract longword high @@ -238,65 +238,65 @@ def MSKWHi : OFormL<0x12, 0x52, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "MSKWH $RA,$L,$RC">; //Mask word high def MSKWL : OForm< 0x12, 0x12, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKWL $RA,$RB,$RC">; //Mask word low def MSKWLi : OFormL<0x12, 0x12, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "MSKWL $RA,$L,$RC">; //Mask word low -def MULL : OForm< 0x13, 0x00, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MULL $RA,$RB,$RC">; //Multiply longword -def MULLi : OFormL<0x13, 0x00, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "MULL $RA,$L,$RC">; //Multiply longword -def MULQ : OForm< 0x13, 0x20, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MULQ $RA,$RB,$RC">; //Multiply quadword -def MULQi : OFormL<0x13, 0x20, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "MULQ $RA,$L,$RC">; //Multiply quadword -def ORNOT : OForm< 0x11, 0x28, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ORNOT $RA,$RB,$RC">; //Logical sum with complement -def ORNOTi : OFormL<0x11, 0x28, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "ORNOT $RA,$L,$RC">; //Logical sum with complement -def S4ADDL : OForm< 0x10, 0x02, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4ADDL $RA,$RB,$RC">; //Scaled add longword by 4 -def S4ADDLi : OFormL<0x10, 0x02, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "S4ADDL $RA,$L,$RC">; //Scaled add longword by 4 -def S4ADDQ : OForm< 0x10, 0x22, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4ADDQ $RA,$RB,$RC">; //Scaled add quadword by 4 -def S4ADDQi : OFormL<0x10, 0x22, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "S4ADDQ $RA,$L,$RC">; //Scaled add quadword by 4 -def S4SUBL : OForm< 0x10, 0x0B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4SUBL $RA,$RB,$RC">; //Scaled subtract longword by 4 -def S4SUBLi : OFormL<0x10, 0x0B, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "S4SUBL $RA,$L,$RC">; //Scaled subtract longword by 4 -def S4SUBQ : OForm< 0x10, 0x2B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4SUBQ $RA,$RB,$RC">; //Scaled subtract quadword by 4 -def S4SUBQi : OFormL<0x10, 0x2B, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "S4SUBQ $RA,$L,$RC">; //Scaled subtract quadword by 4 -def S8ADDL : OForm< 0x10, 0x12, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8ADDL $RA,$RB,$RC">; //Scaled add longword by 8 -def S8ADDLi : OFormL<0x10, 0x12, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "S8ADDL $RA,$L,$RC">; //Scaled add longword by 8 -def S8ADDQ : OForm< 0x10, 0x32, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8ADDQ $RA,$RB,$RC">; //Scaled add quadword by 8 -def S8ADDQi : OFormL<0x10, 0x32, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "S8ADDQ $RA,$L,$RC">; //Scaled add quadword by 8 -def S8SUBL : OForm< 0x10, 0x1B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8SUBL $RA,$RB,$RC">; //Scaled subtract longword by 8 -def S8SUBLi : OFormL<0x10, 0x1B, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "S8SUBL $RA,$L,$RC">; //Scaled subtract longword by 8 -def S8SUBQ : OForm< 0x10, 0x3B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8SUBQ $RA,$RB,$RC">; //Scaled subtract quadword by 8 -def S8SUBQi : OFormL<0x10, 0x3B, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "S8SUBQ $RA,$L,$RC">; //Scaled subtract quadword by 8 +def MULL : OForm< 0x13, 0x00, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "mull $RA,$RB,$RC">; //Multiply longword +def MULLi : OFormL<0x13, 0x00, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "mull $RA,$L,$RC">; //Multiply longword +def MULQ : OForm< 0x13, 0x20, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "mulq $RA,$RB,$RC">; //Multiply quadword +def MULQi : OFormL<0x13, 0x20, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "mulq $RA,$L,$RC">; //Multiply quadword +def ORNOT : OForm< 0x11, 0x28, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ornot $RA,$RB,$RC">; //Logical sum with complement +def ORNOTi : OFormL<0x11, 0x28, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "ornot $RA,$L,$RC">; //Logical sum with complement +def S4ADDL : OForm< 0x10, 0x02, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "s4addl $RA,$RB,$RC">; //Scaled add longword by 4 +def S4ADDLi : OFormL<0x10, 0x02, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "s4addl $RA,$L,$RC">; //Scaled add longword by 4 +def S4ADDQ : OForm< 0x10, 0x22, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "s4addq $RA,$RB,$RC">; //Scaled add quadword by 4 +def S4ADDQi : OFormL<0x10, 0x22, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "s4addq $RA,$L,$RC">; //Scaled add quadword by 4 +def S4SUBL : OForm< 0x10, 0x0B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "s4subl $RA,$RB,$RC">; //Scaled subtract longword by 4 +def S4SUBLi : OFormL<0x10, 0x0B, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "s4subl $RA,$L,$RC">; //Scaled subtract longword by 4 +def S4SUBQ : OForm< 0x10, 0x2B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "s4subq $RA,$RB,$RC">; //Scaled subtract quadword by 4 +def S4SUBQi : OFormL<0x10, 0x2B, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "s4subq $RA,$L,$RC">; //Scaled subtract quadword by 4 +def S8ADDL : OForm< 0x10, 0x12, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "s8addl $RA,$RB,$RC">; //Scaled add longword by 8 +def S8ADDLi : OFormL<0x10, 0x12, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "s8addl $RA,$L,$RC">; //Scaled add longword by 8 +def S8ADDQ : OForm< 0x10, 0x32, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "s8addq $RA,$RB,$RC">; //Scaled add quadword by 8 +def S8ADDQi : OFormL<0x10, 0x32, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "s8addq $RA,$L,$RC">; //Scaled add quadword by 8 +def S8SUBL : OForm< 0x10, 0x1B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "s8subl $RA,$RB,$RC">; //Scaled subtract longword by 8 +def S8SUBLi : OFormL<0x10, 0x1B, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "s8subl $RA,$L,$RC">; //Scaled subtract longword by 8 +def S8SUBQ : OForm< 0x10, 0x3B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "s8subq $RA,$RB,$RC">; //Scaled subtract quadword by 8 +def S8SUBQi : OFormL<0x10, 0x3B, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "s8subq $RA,$L,$RC">; //Scaled subtract quadword by 8 def SEXTB : OForm< 0x1C, 0x00, (ops GPRC:$RC, GPRC:$RB), "sextb $RB,$RC">; //Sign extend byte def SEXTBi : OFormL<0x1C, 0x00, (ops GPRC:$RC, u8imm:$L), "sextb $L,$RC">; //Sign extend byte def SEXTW : OForm< 0x1C, 0x01, (ops GPRC:$RC, GPRC:$RB), "sextw $RB,$RC">; //Sign extend word def SEXTWi : OFormL<0x1C, 0x01, (ops GPRC:$RC, u8imm:$L), "sextw $L,$RC">; //Sign extend word -def SL : OForm< 0x12, 0x39, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SLL $RA,$RB,$RC">; //Shift left logical -def SLi : OFormL<0x12, 0x39, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "SLL $RA,$L,$RC">; //Shift left logical -def SRA : OForm< 0x12, 0x3C, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SRA $RA,$RB,$RC">; //Shift right arithmetic -def SRAi : OFormL<0x12, 0x3C, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "SRA $RA,$L,$RC">; //Shift right arithmetic -def SRL : OForm< 0x12, 0x34, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SRL $RA,$RB,$RC">; //Shift right logical - -def SRLi : OFormL<0x12, 0x34, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "SRL $RA,$L,$RC">; //Shift right logical -def SUBL : OForm< 0x10, 0x09, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SUBL $RA,$RB,$RC">; //Subtract longword -def SUBLi : OFormL<0x10, 0x09, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "SUBL $RA,$L,$RC">; //Subtract longword -def SUBQ : OForm< 0x10, 0x29, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SUBQ $RA,$RB,$RC">; //Subtract quadword -def SUBQi : OFormL<0x10, 0x29, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "SUBQ $RA,$L,$RC">; //Subtract quadword -def UMULH : OForm< 0x13, 0x30, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "UMULH $RA,$RB,$RC">; //Unsigned multiply quadword high -def UMULHi : OFormL<0x13, 0x30, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "UMULH $RA,$L,$RC">; //Unsigned multiply quadword high -def XOR : OForm< 0x11, 0x40, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "XOR $RA,$RB,$RC">; //Logical difference -def XORi : OFormL<0x11, 0x40, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "XOR $RA,$L,$RC">; //Logical difference -def ZAP : OForm< 0x12, 0x30, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ZAP $RA,$RB,$RC">; //Zero bytes -def ZAPi : OFormL<0x12, 0x30, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "ZAP $RA,$L,$RC">; //Zero bytes -def ZAPNOT : OForm< 0x12, 0x31, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ZAPNOT $RA,$RB,$RC">; //Zero bytes not -def ZAPNOTi : OFormL<0x12, 0x31, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "ZAPNOT $RA,$L,$RC">; //Zero bytes not +def SL : OForm< 0x12, 0x39, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "sll $RA,$RB,$RC">; //Shift left logical +def SLi : OFormL<0x12, 0x39, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "sll $RA,$L,$RC">; //Shift left logical +def SRA : OForm< 0x12, 0x3C, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "sra $RA,$RB,$RC">; //Shift right arithmetic +def SRAi : OFormL<0x12, 0x3C, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "sra $RA,$L,$RC">; //Shift right arithmetic +def SRL : OForm< 0x12, 0x34, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "srl $RA,$RB,$RC">; //Shift right logical + +def SRLi : OFormL<0x12, 0x34, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "srl $RA,$L,$RC">; //Shift right logical +def SUBL : OForm< 0x10, 0x09, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "subl $RA,$RB,$RC">; //Subtract longword +def SUBLi : OFormL<0x10, 0x09, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "subl $RA,$L,$RC">; //Subtract longword +def SUBQ : OForm< 0x10, 0x29, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "subq $RA,$RB,$RC">; //Subtract quadword +def SUBQi : OFormL<0x10, 0x29, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "subq $RA,$L,$RC">; //Subtract quadword +def UMULH : OForm< 0x13, 0x30, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "umulh $RA,$RB,$RC">; //Unsigned multiply quadword high +def UMULHi : OFormL<0x13, 0x30, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "umulh $RA,$L,$RC">; //Unsigned multiply quadword high +def XOR : OForm< 0x11, 0x40, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "xor $RA,$RB,$RC">; //Logical difference +def XORi : OFormL<0x11, 0x40, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "xor $RA,$L,$RC">; //Logical difference +def ZAP : OForm< 0x12, 0x30, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "zap $RA,$RB,$RC">; //Zero bytes +def ZAPi : OFormL<0x12, 0x30, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "zap $RA,$L,$RC">; //Zero bytes +def ZAPNOT : OForm< 0x12, 0x31, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "zapnot $RA,$RB,$RC">; //Zero bytes not +def ZAPNOTi : OFormL<0x12, 0x31, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "zapnot $RA,$L,$RC">; //Zero bytes not //Comparison, int -def CMPBGE : OForm< 0x10, 0x0F, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPBGE $RA,$RB,$RC">; //Compare byte -def CMPBGEi : OFormL<0x10, 0x0F, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "CMPBGE $RA,$L,$RC">; //Compare byte -def CMPEQ : OForm< 0x10, 0x2D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPEQ $RA,$RB,$RC">; //Compare signed quadword equal -def CMPEQi : OFormL<0x10, 0x2D, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "CMPEQ $RA,$L,$RC">; //Compare signed quadword equal -def CMPLE : OForm< 0x10, 0x6D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPLE $RA,$RB,$RC">; //Compare signed quadword less than or equal -def CMPLEi : OFormL<0x10, 0x6D, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "CMPLE $RA,$L,$RC">; //Compare signed quadword less than or equal -def CMPLT : OForm< 0x10, 0x4D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPLT $RA,$RB,$RC">; //Compare signed quadword less than -def CMPLTi : OFormL<0x10, 0x4D, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "CMPLT $RA,$L,$RC">; //Compare signed quadword less than -def CMPULE : OForm< 0x10, 0x3D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPULE $RA,$RB,$RC">; //Compare unsigned quadword less than or equal -def CMPULEi : OFormL<0x10, 0x3D, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "CMPULE $RA,$L,$RC">; //Compare unsigned quadword less than or equal -def CMPULT : OForm< 0x10, 0x1D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPULT $RA,$RB,$RC">; //Compare unsigned quadword less than -def CMPULTi : OFormL<0x10, 0x1D, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "CMPULT $RA,$L,$RC">; //Compare unsigned quadword less than +def CMPBGE : OForm< 0x10, 0x0F, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "cmpbge $RA,$RB,$RC">; //Compare byte +def CMPBGEi : OFormL<0x10, 0x0F, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "cmpbge $RA,$L,$RC">; //Compare byte +def CMPEQ : OForm< 0x10, 0x2D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "cmpeq $RA,$RB,$RC">; //Compare signed quadword equal +def CMPEQi : OFormL<0x10, 0x2D, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "cmpeq $RA,$L,$RC">; //Compare signed quadword equal +def CMPLE : OForm< 0x10, 0x6D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "cmple $RA,$RB,$RC">; //Compare signed quadword less than or equal +def CMPLEi : OFormL<0x10, 0x6D, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "cmple $RA,$L,$RC">; //Compare signed quadword less than or equal +def CMPLT : OForm< 0x10, 0x4D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "cmplt $RA,$RB,$RC">; //Compare signed quadword less than +def CMPLTi : OFormL<0x10, 0x4D, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "cmplt $RA,$L,$RC">; //Compare signed quadword less than +def CMPULE : OForm< 0x10, 0x3D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "cmpule $RA,$RB,$RC">; //Compare unsigned quadword less than or equal +def CMPULEi : OFormL<0x10, 0x3D, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "cmpule $RA,$L,$RC">; //Compare unsigned quadword less than or equal +def CMPULT : OForm< 0x10, 0x1D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "cmpult $RA,$RB,$RC">; //Compare unsigned quadword less than +def CMPULTi : OFormL<0x10, 0x1D, (ops GPRC:$RC, GPRC:$RA, u8imm:$L), "cmpult $RA,$L,$RC">; //Compare unsigned quadword less than //Comparison, FP def CMPTEQ : FPForm<0x16, 0x0A5, (ops FPRC:$RC, FPRC:$RA, FPRC:$RB), "cmpteq/su $RA,$RB,$RC">; //Compare T_floating equal From alenhar2 at cs.uiuc.edu Thu Apr 7 12:19:29 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 7 Apr 2005 12:19:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504071719.j37HJTwC001244@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.86 -> 1.87 --- Log message: fixup magic constant making code. tested by thousands of random divisions.... by 10000. ok, so random divisors would be good too, but this at least fixes some things --- Diffs of the changes: (+10 -10) AlphaISelPattern.cpp | 20 ++++++++++---------- 1 files changed, 10 insertions(+), 10 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.86 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.87 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.86 Thu Apr 7 09:18:13 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Thu Apr 7 12:19:16 2005 @@ -413,7 +413,7 @@ ad = abs(d); t = two63 + ((uint64_t)d >> 63); anc = t - 1 - t%ad; // absolute value of nc - p = 31; // initialize p + p = 63; // initialize p q1 = two63/anc; // initialize q1 = 2p/abs(nc) r1 = two63 - q1*anc; // initialize r1 = rem(2p,abs(nc)) q2 = two63/ad; // initialize q2 = 2p/abs(d) @@ -450,11 +450,11 @@ struct mu magu; magu.a = 0; // initialize "add" indicator nc = - 1 - (-d)%d; - p = 31; // initialize p - q1 = 0x8000000000000000ll/nc; // initialize q1 = 2p/nc - r1 = 0x8000000000000000ll - q1*nc; // initialize r1 = rem(2p,nc) - q2 = 0x7FFFFFFFFFFFFFFFll/d; // initialize q2 = (2p-1)/d - r2 = 0x7FFFFFFFFFFFFFFFll - q2*d; // initialize r2 = rem((2p-1),d) + p = 63; // initialize p + q1 = 0x8000000000000000ull/nc; // initialize q1 = 2p/nc + r1 = 0x8000000000000000ull - q1*nc; // initialize r1 = rem(2p,nc) + q2 = 0x7FFFFFFFFFFFFFFFull/d; // initialize q2 = (2p-1)/d + r2 = 0x7FFFFFFFFFFFFFFFull - q2*d; // initialize r2 = rem((2p-1),d) do { p = p + 1; if (r1 >= nc - r1 ) { @@ -466,19 +466,19 @@ r1 = 2*r1; // update r1 } if (r2 + 1 >= d - r2) { - if (q2 >= 0x7FFFFFFFFFFFFFFFll) magu.a = 1; + if (q2 >= 0x7FFFFFFFFFFFFFFFull) magu.a = 1; q2 = 2*q2 + 1; // update q2 r2 = 2*r2 + 1 - d; // update r2 } else { - if (q2 >= 0x8000000000000000ll) magu.a = 1; + if (q2 >= 0x8000000000000000ull) magu.a = 1; q2 = 2*q2; // update q2 r2 = 2*r2 + 1; // update r2 } delta = d - 1 - r2; } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); magu.m = q2 + 1; // resulting magic number - magu.s = p - 32; // resulting shift + magu.s = p - 64; // resulting shift return magu; } @@ -487,7 +487,7 @@ /// multiplying by a magic number. See: /// SDOperand ISel::BuildSDIVSequence(SDOperand N) { - int d = (int)cast(N.getOperand(1))->getSignExtended(); + int64_t d = (int64_t)cast(N.getOperand(1))->getSignExtended(); ms magics = magic(d); // Multiply the numerator (operand 0) by the magic value SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i64, N.getOperand(0), From alenhar2 at cs.uiuc.edu Thu Apr 7 12:47:14 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 7 Apr 2005 12:47:14 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Alpha/s4addq.ll Message-ID: <200504071747.j37HlENj001487@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Alpha: s4addq.ll updated: 1.2 -> 1.3 --- Log message: match case change in codegen --- Diffs of the changes: (+1 -1) s4addq.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/Alpha/s4addq.ll diff -u llvm/test/Regression/CodeGen/Alpha/s4addq.ll:1.2 llvm/test/Regression/CodeGen/Alpha/s4addq.ll:1.3 --- llvm/test/Regression/CodeGen/Alpha/s4addq.ll:1.2 Wed Apr 6 15:59:03 2005 +++ llvm/test/Regression/CodeGen/Alpha/s4addq.ll Thu Apr 7 12:47:00 2005 @@ -1,5 +1,5 @@ ; Make sure this testcase codegens to the S4ADDQ instruction -; RUN: llvm-as < %s | llc -march=alpha | grep 'S4ADDQ' +; RUN: llvm-as < %s | llc -march=alpha | grep 's4addq' implementation ; Functions: From lattner at cs.uiuc.edu Thu Apr 7 13:15:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 13:15:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504071815.j37IFFJB006240@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.60 -> 1.61 --- Log message: This patch does two things. First, it canonicalizes 'X >= C' -> 'X > C-1' (likewise for <= >=u >=u). Second, it implements a special case hack to turn 'X gtu SINTMAX' -> 'X lt 0' On powerpc, for example, this changes this: lis r2, 32767 ori r2, r2, 65535 cmplw cr0, r3, r2 bgt .LBB_test_2 into: cmpwi cr0, r3, 0 blt .LBB_test_2 --- Diffs of the changes: (+49 -7) SelectionDAG.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 49 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.60 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.61 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.60 Wed Apr 6 19:30:13 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Apr 7 13:14:58 2005 @@ -375,9 +375,10 @@ case ISD::SETTRUE2: return getConstant(1, VT); } - if (ConstantSDNode *N1C = dyn_cast(N1.Val)) - if (ConstantSDNode *N2C = dyn_cast(N2.Val)) { - uint64_t C1 = N1C->getValue(), C2 = N2C->getValue(); + if (ConstantSDNode *N2C = dyn_cast(N2.Val)) { + uint64_t C2 = N2C->getValue(); + if (ConstantSDNode *N1C = dyn_cast(N1.Val)) { + uint64_t C1 = N1C->getValue(); // Sign extend the operands if required if (ISD::isSignedIntSetCC(Cond)) { @@ -398,11 +399,52 @@ case ISD::SETLE: return getConstant((int64_t)C1 <= (int64_t)C2, VT); case ISD::SETGE: return getConstant((int64_t)C1 >= (int64_t)C2, VT); } - } else { - // Ensure that the constant occurs on the RHS. - Cond = ISD::getSetCCSwappedOperands(Cond); - std::swap(N1, N2); + } else if (1) { + uint64_t MinVal, MaxVal; + unsigned OperandBitSize = MVT::getSizeInBits(N2C->getValueType(0)); + if (ISD::isSignedIntSetCC(Cond)) { + MinVal = 1ULL << (OperandBitSize-1); + if (OperandBitSize != 1) // Avoid X >> 64, which is undefined. + MaxVal = ~0ULL >> (65-OperandBitSize); + else + MaxVal = 0; + } else { + MinVal = 0; + MaxVal = ~0ULL >> (64-OperandBitSize); + } + + // Canonicalize GE/LE comparisons to use GT/LT comparisons. + if (Cond == ISD::SETGE || Cond == ISD::SETUGE) { + if (C2 == MinVal) return getConstant(1, VT); // X >= MIN --> true + --C2; // X >= C1 --> X > (C1-1) + Cond = (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT; + N2 = getConstant(C2, N2.getValueType()); + N2C = cast(N2.Val); + } + + if (Cond == ISD::SETLE || Cond == ISD::SETULE) { + if (C2 == MaxVal) return getConstant(1, VT); // X <= MAX --> true + ++C2; // X <= C1 --> X < (C1+1) + Cond = (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT; + N2 = getConstant(C2, N2.getValueType()); + N2C = cast(N2.Val); + } + + // If we have "setcc X, C1", check to see if we can shrink the immediate + // by changing cc. + + // SETUGT X, SINTMAX -> SETLT X, 0 + if (Cond == ISD::SETUGT && OperandBitSize != 1 && + C2 == (~0ULL >> (65-OperandBitSize))) + return getSetCC(ISD::SETLT, VT, N1, getConstant(0, N2.getValueType())); + + // FIXME: Implement the rest of these. + } + } else if (isa(N1.Val)) { + // Ensure that the constant occurs on the RHS. + return getSetCC(ISD::getSetCCSwappedOperands(Cond), VT, N2, N1); + } if (ConstantFPSDNode *N1C = dyn_cast(N1.Val)) if (ConstantFPSDNode *N2C = dyn_cast(N2.Val)) { From alenhar2 at cs.uiuc.edu Thu Apr 7 13:15:41 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 7 Apr 2005 13:15:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504071815.j37IFfXF006259@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.87 -> 1.88 --- Log message: fix a small optimization opertunity and make gcc happy --- Diffs of the changes: (+1 -3) AlphaISelPattern.cpp | 4 +--- 1 files changed, 1 insertion(+), 3 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.87 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.88 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.87 Thu Apr 7 12:19:16 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Thu Apr 7 13:15:28 2005 @@ -1090,7 +1090,7 @@ unsigned ISel::SelectExpr(SDOperand N) { unsigned Result; - unsigned Tmp1, Tmp2, Tmp3; + unsigned Tmp1, Tmp2 = 0, Tmp3; unsigned Opc = 0; unsigned opcode = N.getOpcode(); @@ -1448,7 +1448,6 @@ Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); } return Result; @@ -1810,7 +1809,6 @@ { unsigned k = ExactLog2(abs(CSD->getSignExtended())); Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = MakeReg(MVT::i64); if (k == 1) Tmp2 = Tmp1; else From lattner at cs.uiuc.edu Thu Apr 7 13:59:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 13:59:10 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504071859.j37IxA27006912@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.61 -> 1.62 --- Log message: Remove somethign I had for testing --- Diffs of the changes: (+1 -1) SelectionDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.61 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.62 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.61 Thu Apr 7 13:14:58 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Apr 7 13:58:54 2005 @@ -399,7 +399,7 @@ case ISD::SETLE: return getConstant((int64_t)C1 <= (int64_t)C2, VT); case ISD::SETGE: return getConstant((int64_t)C1 >= (int64_t)C2, VT); } - } else if (1) { + } else { uint64_t MinVal, MaxVal; unsigned OperandBitSize = MVT::getSizeInBits(N2C->getValueType(0)); if (ISD::isSignedIntSetCC(Cond)) { From lattner at cs.uiuc.edu Thu Apr 7 14:41:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 14:41:35 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200504071941.j37JfZWN016126@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.8 -> 1.9 --- Log message: Allow targets which produce setcc results in non-MVT::i1 registers to describe what the contents of the top bits of these registers are, in the common cases of targets that sign and zero extend the results. --- Diffs of the changes: (+23 -1) TargetLowering.h | 24 +++++++++++++++++++++++- 1 files changed, 23 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.8 llvm/include/llvm/Target/TargetLowering.h:1.9 --- llvm/include/llvm/Target/TargetLowering.h:1.8 Fri Mar 25 19:30:30 2005 +++ llvm/include/llvm/Target/TargetLowering.h Thu Apr 7 14:41:18 2005 @@ -59,6 +59,12 @@ Extend, // Oversized shift pulls in zeros or sign bits. }; + enum SetCCResultValue { + UndefinedSetCCResult, // SetCC returns a garbage/unknown extend. + ZeroOrOneSetCCResult, // SetCC returns a zero extended result. + ZeroOrNegativeOneSetCCResult, // SetCC returns a sign extended result. + }; + TargetLowering(TargetMachine &TM); virtual ~TargetLowering(); @@ -68,9 +74,17 @@ bool isLittleEndian() const { return IsLittleEndian; } MVT::ValueType getPointerTy() const { return PointerTy; } MVT::ValueType getShiftAmountTy() const { return ShiftAmountTy; } - MVT::ValueType getSetCCResultTy() const { return SetCCResultTy; } OutOfRangeShiftAmount getShiftAmountFlavor() const {return ShiftAmtHandling; } + /// getSetCCResultTy - Return the ValueType of the result of setcc operations. + /// + MVT::ValueType getSetCCResultTy() const { return SetCCResultTy; } + + /// getSetCCResultContents - For targets without boolean registers, this flag + /// returns information about the contents of the high-bits in the setcc + /// result register. + SetCCResultValue getSetCCResultContents() const { return SetCCResultContents;} + /// getRegClassFor - Return the register class that should be used for the /// specified value type. This may only be called on legal types. TargetRegisterClass *getRegClassFor(MVT::ValueType VT) const { @@ -183,6 +197,10 @@ /// of a setcc operation. This defaults to the pointer type. void setSetCCResultType(MVT::ValueType VT) { SetCCResultTy = VT; } + /// setSetCCResultContents - Specify how the target extends the result of a + /// setcc operation in a register. + void setSetCCResultContents(SetCCResultValue Ty) { SetCCResultContents = Ty; } + /// setShiftAmountFlavor - Describe how the target handles out of range shift /// amounts. void setShiftAmountFlavor(OutOfRangeShiftAmount OORSA) { @@ -296,6 +314,10 @@ /// PointerTy. MVT::ValueType SetCCResultTy; + /// SetCCResultContents - Information about the contents of the high-bits in + /// the result of a setcc comparison operation. + SetCCResultValue SetCCResultContents; + /// RegClassForVT - This indicates the default register class to use for /// each ValueType the target supports natively. TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE]; From lattner at cs.uiuc.edu Thu Apr 7 14:42:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 14:42:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200504071942.j37Jg0Uh016148@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.100 -> 1.101 --- Log message: X86 zero extends setcc results --- Diffs of the changes: (+1 -0) X86ISelPattern.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.100 llvm/lib/Target/X86/X86ISelPattern.cpp:1.101 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.100 Tue Apr 5 23:21:07 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Thu Apr 7 14:41:46 2005 @@ -43,6 +43,7 @@ // X86 is wierd, it always uses i8 for shift amounts and setcc results. setShiftAmountType(MVT::i8); setSetCCResultType(MVT::i8); + setSetCCResultContents(ZeroOrOneSetCCResult); setShiftAmountFlavor(Mask); // shl X, 32 == shl X, 0 // Set up the register classes. From lattner at cs.uiuc.edu Thu Apr 7 14:42:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 14:42:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504071942.j37Jg2pk016154@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.50 -> 1.51 --- Log message: PowerPC zero extends setcc results --- Diffs of the changes: (+1 -0) PPC32ISelPattern.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.50 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.51 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.50 Wed Apr 6 18:51:40 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Thu Apr 7 14:41:49 2005 @@ -62,6 +62,7 @@ setOperationAction(ISD::UREM, MVT::i32, Expand); setShiftAmountFlavor(Extend); // shl X, 32 == 0 + setSetCCResultContents(ZeroOrOneSetCCResult); addLegalFPImmediate(+0.0); // Necessary for FSEL addLegalFPImmediate(-0.0); // From lattner at cs.uiuc.edu Thu Apr 7 14:44:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 14:44:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504071944.j37Ji7Xp016168@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.62 -> 1.63 --- Log message: If a target zero or sign extends the result of its setcc, allow folding of this into sign/zero extension instructions later. On PPC, for example, this testcase: %G = external global sbyte implementation void %test(int %X, int %Y) { %C = setlt int %X, %Y %D = cast bool %C to sbyte store sbyte %D, sbyte* %G ret void } Now codegens to: cmpw cr0, r3, r4 li r3, 1 li r4, 0 blt .LBB_test_2 ; .LBB_test_1: ; or r3, r4, r4 .LBB_test_2: ; addis r2, r2, ha16(L_G$non_lazy_ptr-"L00000$pb") lwz r2, lo16(L_G$non_lazy_ptr-"L00000$pb")(r2) stb r3, 0(r2) instead of: cmpw cr0, r3, r4 li r3, 1 li r4, 0 blt .LBB_test_2 ; .LBB_test_1: ; or r3, r4, r4 .LBB_test_2: ; *** rlwinm r3, r3, 0, 31, 31 addis r2, r2, ha16(L_G$non_lazy_ptr-"L00000$pb") lwz r2, lo16(L_G$non_lazy_ptr-"L00000$pb")(r2) stb r3, 0(r2) --- Diffs of the changes: (+13 -1) SelectionDAG.cpp | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.62 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.63 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.62 Thu Apr 7 13:58:54 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Apr 7 14:43:53 2005 @@ -585,7 +585,7 @@ break; case ISD::ZERO_EXTEND: if (Operand.getValueType() == VT) return Operand; // noop extension - if (OpOpcode == ISD::ZERO_EXTEND) + if (OpOpcode == ISD::ZERO_EXTEND) // (zext (zext x)) -> (zext x) return getNode(ISD::ZERO_EXTEND, VT, Operand.Val->getOperand(0)); break; case ISD::TRUNCATE: @@ -1025,6 +1025,18 @@ return N1; } + // If we are extending the result of a setcc, and we already know the + // contents of the top bits, eliminate the extension. + if (N1.getOpcode() == ISD::SETCC) + switch (TLI.getSetCCResultContents()) { + case TargetLowering::UndefinedSetCCResult: break; + case TargetLowering::ZeroOrOneSetCCResult: + if (Opcode == ISD::ZERO_EXTEND_INREG) return N1; + break; + case TargetLowering::ZeroOrNegativeOneSetCCResult: + if (Opcode == ISD::SIGN_EXTEND_INREG) return N1; + break; + } break; } From alenhar2 at cs.uiuc.edu Thu Apr 7 15:11:49 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 7 Apr 2005 15:11:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504072011.j37KBnCe016301@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.88 -> 1.89 --- Log message: Alpha zero extends setcc results --- Diffs of the changes: (+1 -0) AlphaISelPattern.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.88 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.89 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.88 Thu Apr 7 13:15:28 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Thu Apr 7 15:11:32 2005 @@ -53,6 +53,7 @@ //I am having problems with shr n ubyte 1 setShiftAmountType(MVT::i64); setSetCCResultType(MVT::i64); + setSetCCResultContents(ZeroOrOneSetCCResult); addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass); addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass); From natebegeman at mac.com Thu Apr 7 15:30:11 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 7 Apr 2005 15:30:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504072030.PAA16793@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.51 -> 1.52 --- Log message: Optimized code sequences for setcc reg, 0 Optimized code sequence for (a < 0) ? b : 0 --- Diffs of the changes: (+77 -4) PPC32ISelPattern.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 77 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.51 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.52 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.51 Thu Apr 7 14:41:49 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Thu Apr 7 15:30:01 2005 @@ -1898,8 +1898,64 @@ case ISD::SETCC: if (SetCCSDNode *SetCC = dyn_cast(Node)) { + // We can codegen setcc op, 0 very efficiently compared to a conditional + // branch. Check for that here. + if (ConstantSDNode *CN = + dyn_cast(SetCC->getOperand(1).Val)) { + if (CN->getValue() == 0) { + Tmp1 = SelectExpr(SetCC->getOperand(0)); + switch (SetCC->getCondition()) { + default: assert(0 && "Unhandled SetCC condition"); abort(); + case ISD::SETEQ: + case ISD::SETULE: + Tmp2 = MakeReg(MVT::i32); + BuildMI(BB, PPC::CNTLZW, 1, Tmp2).addReg(Tmp1); + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp2).addImm(27) + .addImm(5).addImm(31); + break; + case ISD::SETNE: + case ISD::SETUGT: + Tmp2 = MakeReg(MVT::i32); + BuildMI(BB, PPC::ADDIC, 2, Tmp2).addReg(Tmp1).addSImm(-1); + BuildMI(BB, PPC::SUBFE, 2, Result).addReg(Tmp2).addReg(Tmp1); + break; + case ISD::SETULT: + BuildMI(BB, PPC::LI, 1, Result).addSImm(0); + break; + case ISD::SETLT: + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(1) + .addImm(31).addImm(31); + break; + case ISD::SETLE: + Tmp2 = MakeReg(MVT::i32); + Tmp3 = MakeReg(MVT::i32); + BuildMI(BB, PPC::NEG, 2, Tmp2).addReg(Tmp1); + BuildMI(BB, PPC::ORC, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp3).addImm(1) + .addImm(31).addImm(31); + break; + case ISD::SETGT: + Tmp2 = MakeReg(MVT::i32); + Tmp3 = MakeReg(MVT::i32); + BuildMI(BB, PPC::NEG, 2, Tmp2).addReg(Tmp1); + BuildMI(BB, PPC::ANDC, 2, Tmp3).addReg(Tmp2).addReg(Tmp1); + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp3).addImm(1) + .addImm(31).addImm(31); + break; + case ISD::SETUGE: + BuildMI(BB, PPC::LI, 1, Result).addSImm(1); + break; + case ISD::SETGE: + BuildMI(BB, PPC::RLWINM, 4, Tmp2).addReg(Tmp1).addImm(1) + .addImm(31).addImm(31); + BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp2).addImm(1); + break; + } + return Result; + } + } + Opc = SelectSetCR0(N); - unsigned TrueValue = MakeReg(MVT::i32); BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1); unsigned FalseValue = MakeReg(MVT::i32); @@ -1946,6 +2002,25 @@ return 0; case ISD::SELECT: { + // We can codegen select (a < 0) ? b : 0 very efficiently compared to a + // conditional branch. Check for that here. + if (SetCCSDNode *SetCC = dyn_cast(N.getOperand(0).Val)) { + if (ConstantSDNode *CN = + dyn_cast(SetCC->getOperand(1).Val)) { + if (ConstantSDNode *CNF = + dyn_cast(N.getOperand(2).Val)) { + if (CN->getValue() == 0 && CNF->getValue() == 0 && + SetCC->getCondition() == ISD::SETLT) { + Tmp1 = SelectExpr(N.getOperand(1)); // TRUE value + Tmp2 = SelectExpr(SetCC->getOperand(0)); + Tmp3 = MakeReg(MVT::i32); + BuildMI(BB, PPC::SRAWI, 2, Tmp3).addReg(Tmp2).addImm(31); + BuildMI(BB, PPC::AND, 2, Result).addReg(Tmp1).addReg(Tmp3); + return Result; + } + } + } + } unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE Opc = SelectSetCR0(N.getOperand(0)); @@ -1986,8 +2061,6 @@ BB = sinkMBB; BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue) .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB); - - // FIXME: Select i64? return Result; } @@ -2123,7 +2196,7 @@ } else { //ISD::TRUNCSTORE switch(cast(Node)->getExtraValueType()) { default: assert(0 && "unknown Type in store"); - case MVT::i1: //FIXME: DAG does not promote this load + case MVT::i1: case MVT::i8: Opc = PPC::STB; break; case MVT::i16: Opc = PPC::STH; break; } From lattner at cs.uiuc.edu Thu Apr 7 22:58:37 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 22:58:37 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2005-05-07-UDivSelectCrash.ll Message-ID: <200504080358.j383wb6w019480@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2005-05-07-UDivSelectCrash.ll added (r1.1) --- Log message: new testcase that crashes the instcombiner. --- Diffs of the changes: (+7 -0) 2005-05-07-UDivSelectCrash.ll | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/2005-05-07-UDivSelectCrash.ll diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/2005-05-07-UDivSelectCrash.ll:1.1 *** /dev/null Thu Apr 7 22:58:31 2005 --- llvm/test/Regression/Transforms/InstCombine/2005-05-07-UDivSelectCrash.ll Thu Apr 7 22:58:21 2005 *************** *** 0 **** --- 1,7 ---- + ; RUN: llvm-as < %s | opt -instcombine -disable-output + + uint %test(bool %C, uint %tmp.15) { + %tmp.16 = select bool %C, uint 8, uint 1 + %tmp.18 = div uint %tmp.15, %tmp.16 + ret uint %tmp.18 + } From lattner at cs.uiuc.edu Thu Apr 7 23:03:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 7 Apr 2005 23:03:40 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200504080403.j3843eGA019952@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.320 -> 1.321 --- Log message: Fix bug: InstCombine/2005-05-07-UDivSelectCrash.ll --- Diffs of the changes: (+16 -14) InstructionCombining.cpp | 30 ++++++++++++++++-------------- 1 files changed, 16 insertions(+), 14 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.320 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.321 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.320 Thu Apr 7 12:14:51 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Apr 7 23:03:26 2005 @@ -1068,23 +1068,25 @@ I.setOperand(1, SFO); return &I; } else if (SFO->getValue() == 0) { - I.setOperand(1, STO); + I.setOperand(2, STO); return &I; } - if (uint64_t TSA = Log2(STO->getValue())) - if (uint64_t FSA = Log2(SFO->getValue())) { - Constant *TC = ConstantUInt::get(Type::UByteTy, TSA); - Instruction *TSI = new ShiftInst(Instruction::Shr, Op0, - TC, SI->getName()+".t"); - TSI = InsertNewInstBefore(TSI, I); - - Constant *FC = ConstantUInt::get(Type::UByteTy, FSA); - Instruction *FSI = new ShiftInst(Instruction::Shr, Op0, - FC, SI->getName()+".f"); - FSI = InsertNewInstBefore(FSI, I); - return new SelectInst(SI->getOperand(0), TSI, FSI); - } + uint64_t TVA = STO->getValue(), FVA = SFO->getValue(); + unsigned TSA = 0, FSA = 0; + if ((TVA == 1 || (TSA = Log2(TVA))) && // Log2 fails for 0 & 1. + (FVA == 1 || (FSA = Log2(FVA)))) { + Constant *TC = ConstantUInt::get(Type::UByteTy, TSA); + Instruction *TSI = new ShiftInst(Instruction::Shr, Op0, + TC, SI->getName()+".t"); + TSI = InsertNewInstBefore(TSI, I); + + Constant *FC = ConstantUInt::get(Type::UByteTy, FSA); + Instruction *FSI = new ShiftInst(Instruction::Shr, Op0, + FC, SI->getName()+".f"); + FSI = InsertNewInstBefore(FSI, I); + return new SelectInst(SI->getOperand(0), TSI, FSI); + } } // 0 / X == 0, we don't need to preserve faults! From duraid at octopus.com.au Fri Apr 8 05:02:01 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Fri, 8 Apr 2005 05:02:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp IA64InstrInfo.td Message-ID: <200504081002.FAA31431@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.13 -> 1.14 IA64InstrInfo.td updated: 1.7 -> 1.8 --- Log message: fix bogus division-by-power-of-2 (was wrong for negative input, adds extr insn) fix hack in division (clean up frcpa instruction) --- Diffs of the changes: (+25 -15) IA64ISelPattern.cpp | 27 ++++++++++++++++++++------- IA64InstrInfo.td | 13 +++++-------- 2 files changed, 25 insertions(+), 15 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.13 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.14 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.13 Thu Apr 7 07:33:38 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Fri Apr 8 05:01:48 2005 @@ -1122,9 +1122,21 @@ switch (ponderIntegerDivisionBy(N.getOperand(1), isSigned, Tmp3)) { case 1: // division by a constant that's a power of 2 Tmp1 = SelectExpr(N.getOperand(0)); - if(isSigned) // becomes a shift right: - BuildMI(BB, IA64::SHRS, 2, Result).addReg(Tmp1).addImm(Tmp3); - else + if(isSigned) { // argument could be negative, so emit some code: + unsigned divAmt=Tmp3; + unsigned tempGR1=MakeReg(MVT::i64); + unsigned tempGR2=MakeReg(MVT::i64); + unsigned tempGR3=MakeReg(MVT::i64); + BuildMI(BB, IA64::SHRS, 2, tempGR1) + .addReg(Tmp1).addImm(divAmt-1); + BuildMI(BB, IA64::EXTRU, 3, tempGR2) + .addReg(tempGR1).addImm(64-divAmt).addImm(divAmt); + BuildMI(BB, IA64::ADD, 2, tempGR3) + .addReg(Tmp1).addReg(tempGR2); + BuildMI(BB, IA64::SHRS, 2, Result) + .addReg(tempGR3).addImm(divAmt); + } + else // unsigned div-by-power-of-2 becomes a simple shift right: BuildMI(BB, IA64::SHRU, 2, Result).addReg(Tmp1).addImm(Tmp3); return Result; // early exit } @@ -1171,10 +1183,11 @@ } // we start by computing an approximate reciprocal (good to 9 bits?) - // note, this instruction writes _both_ TmpF5 (answer) and tmpPR (predicate) - // FIXME: or at least, it should!! - BuildMI(BB, IA64::FRCPAS1FLOAT, 2, TmpF5).addReg(TmpF3).addReg(TmpF4); - BuildMI(BB, IA64::FRCPAS1PREDICATE, 2, TmpPR).addReg(TmpF3).addReg(TmpF4); + // note, this instruction writes _both_ TmpF5 (answer) and TmpPR (predicate) + BuildMI(BB, IA64::FRCPAS1, 4) + .addReg(TmpF5, MachineOperand::Def) + .addReg(TmpPR, MachineOperand::Def) + .addReg(TmpF3).addReg(TmpF4); if(!isModulus) { // if this is a divide, we worry about div-by-zero unsigned bogusPR=MakeReg(MVT::i1); // won't appear, due to twoAddress Index: llvm/lib/Target/IA64/IA64InstrInfo.td diff -u llvm/lib/Target/IA64/IA64InstrInfo.td:1.7 llvm/lib/Target/IA64/IA64InstrInfo.td:1.8 --- llvm/lib/Target/IA64/IA64InstrInfo.td:1.7 Thu Apr 7 07:32:24 2005 +++ llvm/lib/Target/IA64/IA64InstrInfo.td Fri Apr 8 05:01:48 2005 @@ -120,6 +120,9 @@ def SHRSI : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s21imm:$imm), "shr $dst = $src1, $imm;;">; +def EXTRU : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm1, u6imm:$imm2), + "extr.u $dst = $src1, $imm1, $imm2;;">; + def DEPZ : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm1, u6imm:$imm2), "dep.z $dst = $src1, $imm1, $imm2;;">; def SXT1 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt1 $dst = $src;;">; @@ -258,14 +261,8 @@ (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3, PR:$qp), "($qp) fnma.s1 $dst = $src1, $src2, $src3;;">; -// FIXME: we 'explode' FRCPA (which should write two registers) into two -// operations that write one each. this is a waste, and is also destroying -// f127. not cool. -def FRCPAS1FLOAT : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), - "frcpa.s1 $dst , p0 = $src1, $src2;;">; -// XXX: this _will_ break things: (f127) -def FRCPAS1PREDICATE : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "frcpa.s1 f127 , $dst = $src1, $src2;; // XXX FIXME!!!!">; +def FRCPAS1 : AForm<0x03, 0x0b, (ops FP:$dstFR, PR:$dstPR, FP:$src1, FP:$src2), + "frcpa.s1 $dstFR, $dstPR = $src1, $src2;;">; def XMAL : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), "xma.l $dst = $src1, $src2, $src3;;">; From alenhar2 at cs.uiuc.edu Fri Apr 8 11:47:01 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 8 Apr 2005 11:47:01 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Alpha/bic.ll eqv.ll neg1.ll not.ll ornot.ll Message-ID: <200504081647.j38Gl1OH031141@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Alpha: bic.ll added (r1.1) eqv.ll added (r1.1) neg1.ll added (r1.1) not.ll added (r1.1) ornot.ll added (r1.1) --- Log message: added some tests to check stupid pattern matching mistakes --- Diffs of the changes: (+52 -0) bic.ll | 11 +++++++++++ eqv.ll | 11 +++++++++++ neg1.ll | 9 +++++++++ not.ll | 10 ++++++++++ ornot.ll | 11 +++++++++++ 5 files changed, 52 insertions(+) Index: llvm/test/Regression/CodeGen/Alpha/bic.ll diff -c /dev/null llvm/test/Regression/CodeGen/Alpha/bic.ll:1.1 *** /dev/null Fri Apr 8 11:46:54 2005 --- llvm/test/Regression/CodeGen/Alpha/bic.ll Fri Apr 8 11:46:44 2005 *************** *** 0 **** --- 1,11 ---- + ; Make sure this testcase codegens to the bic instruction + ; RUN: llvm-as < %s | llc -march=alpha | grep 'bic' + + implementation ; Functions: + + long %bar(long %x, long %y) { + entry: + %tmp.1 = xor long %x, -1 ; [#uses=1] + %tmp.2 = and long %y, long %tmp.1 + ret long %tmp.2 + } Index: llvm/test/Regression/CodeGen/Alpha/eqv.ll diff -c /dev/null llvm/test/Regression/CodeGen/Alpha/eqv.ll:1.1 *** /dev/null Fri Apr 8 11:47:00 2005 --- llvm/test/Regression/CodeGen/Alpha/eqv.ll Fri Apr 8 11:46:44 2005 *************** *** 0 **** --- 1,11 ---- + ; Make sure this testcase codegens to the eqv instruction + ; RUN: llvm-as < %s | llc -march=alpha | grep 'eqv' + + implementation ; Functions: + + long %bar(long %x, long %y) { + entry: + %tmp.1 = xor long %x, -1 ; [#uses=1] + %tmp.2 = xor long %y, long %tmp.1 + ret long %tmp.2 + } Index: llvm/test/Regression/CodeGen/Alpha/neg1.ll diff -c /dev/null llvm/test/Regression/CodeGen/Alpha/neg1.ll:1.1 *** /dev/null Fri Apr 8 11:47:00 2005 --- llvm/test/Regression/CodeGen/Alpha/neg1.ll Fri Apr 8 11:46:44 2005 *************** *** 0 **** --- 1,9 ---- + ; Make sure this testcase codegens to the lda -1 instruction + ; RUN: llvm-as < %s | llc -march=alpha | grep '-1' + + implementation ; Functions: + + long %bar() { + entry: + ret long -1 + } Index: llvm/test/Regression/CodeGen/Alpha/not.ll diff -c /dev/null llvm/test/Regression/CodeGen/Alpha/not.ll:1.1 *** /dev/null Fri Apr 8 11:47:01 2005 --- llvm/test/Regression/CodeGen/Alpha/not.ll Fri Apr 8 11:46:44 2005 *************** *** 0 **** --- 1,10 ---- + ; Make sure this testcase codegens to the ornot instruction + ; RUN: llvm-as < %s | llc -march=alpha | grep 'ornot' + + implementation ; Functions: + + long %bar(long %x) { + entry: + %tmp.1 = xor long %x, -1 ; [#uses=1] + ret long %tmp.1 + } Index: llvm/test/Regression/CodeGen/Alpha/ornot.ll diff -c /dev/null llvm/test/Regression/CodeGen/Alpha/ornot.ll:1.1 *** /dev/null Fri Apr 8 11:47:01 2005 --- llvm/test/Regression/CodeGen/Alpha/ornot.ll Fri Apr 8 11:46:44 2005 *************** *** 0 **** --- 1,11 ---- + ; Make sure this testcase codegens to the ornot instruction + ; RUN: llvm-as < %s | llc -march=alpha | grep 'ornot' + + implementation ; Functions: + + long %bar(long %x, long %y) { + entry: + %tmp.1 = xor long %x, -1 ; [#uses=1] + %tmp.2 = or long %y, long %tmp.1 + ret long %tmp.2 + } From alenhar2 at cs.uiuc.edu Fri Apr 8 11:55:29 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 8 Apr 2005 11:55:29 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Alpha/bic.ll eqv.ll ornot.ll Message-ID: <200504081655.j38GtTPC031518@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Alpha: bic.ll updated: 1.1 -> 1.2 eqv.ll updated: 1.1 -> 1.2 ornot.ll updated: 1.1 -> 1.2 --- Log message: oops --- Diffs of the changes: (+3 -3) bic.ll | 2 +- eqv.ll | 2 +- ornot.ll | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/test/Regression/CodeGen/Alpha/bic.ll diff -u llvm/test/Regression/CodeGen/Alpha/bic.ll:1.1 llvm/test/Regression/CodeGen/Alpha/bic.ll:1.2 --- llvm/test/Regression/CodeGen/Alpha/bic.ll:1.1 Fri Apr 8 11:46:44 2005 +++ llvm/test/Regression/CodeGen/Alpha/bic.ll Fri Apr 8 11:55:15 2005 @@ -6,6 +6,6 @@ long %bar(long %x, long %y) { entry: %tmp.1 = xor long %x, -1 ; [#uses=1] - %tmp.2 = and long %y, long %tmp.1 + %tmp.2 = and long %y, %tmp.1 ret long %tmp.2 } Index: llvm/test/Regression/CodeGen/Alpha/eqv.ll diff -u llvm/test/Regression/CodeGen/Alpha/eqv.ll:1.1 llvm/test/Regression/CodeGen/Alpha/eqv.ll:1.2 --- llvm/test/Regression/CodeGen/Alpha/eqv.ll:1.1 Fri Apr 8 11:46:44 2005 +++ llvm/test/Regression/CodeGen/Alpha/eqv.ll Fri Apr 8 11:55:15 2005 @@ -6,6 +6,6 @@ long %bar(long %x, long %y) { entry: %tmp.1 = xor long %x, -1 ; [#uses=1] - %tmp.2 = xor long %y, long %tmp.1 + %tmp.2 = xor long %y, %tmp.1 ret long %tmp.2 } Index: llvm/test/Regression/CodeGen/Alpha/ornot.ll diff -u llvm/test/Regression/CodeGen/Alpha/ornot.ll:1.1 llvm/test/Regression/CodeGen/Alpha/ornot.ll:1.2 --- llvm/test/Regression/CodeGen/Alpha/ornot.ll:1.1 Fri Apr 8 11:46:44 2005 +++ llvm/test/Regression/CodeGen/Alpha/ornot.ll Fri Apr 8 11:55:15 2005 @@ -6,6 +6,6 @@ long %bar(long %x, long %y) { entry: %tmp.1 = xor long %x, -1 ; [#uses=1] - %tmp.2 = or long %y, long %tmp.1 + %tmp.2 = or long %y, %tmp.1 ret long %tmp.2 } From alenhar2 at cs.uiuc.edu Fri Apr 8 12:29:03 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 8 Apr 2005 12:29:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504081729.j38HT3N8031600@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.89 -> 1.90 --- Log message: collect a few statistics, factor constants (constant loading and mult), fix logic operation pattern matchs, supress FP div when int dividing by a constant --- Diffs of the changes: (+66 -10) AlphaISelPattern.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 66 insertions(+), 10 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.89 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.90 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.89 Thu Apr 7 15:11:32 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Fri Apr 8 12:28:49 2005 @@ -39,6 +39,9 @@ cl::opt EnableAlphaFTOI("enable-alpha-ftoi", cl::desc("Enable use of ftoi* and itof* instructions (ev6 and higher)"), cl::Hidden); + cl::opt EnableAlphaCount("enable-alpha-count", + cl::desc("Print estimates on live ins and outs"), + cl::Hidden); } //===----------------------------------------------------------------------===// @@ -353,6 +356,10 @@ //CCInvMap sometimes (SetNE) we have the inverse CC code for free std::map CCInvMap; + int count_ins; + int count_outs; + bool has_sym; + public: ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {} @@ -361,9 +368,21 @@ /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { DEBUG(BB->dump()); + count_ins = 0; + count_outs = 0; + has_sym = false; + // Codegen the basic block. ISelDAG = &DAG; Select(DAG.getRoot()); + + if(has_sym) + ++count_ins; + if(EnableAlphaCount) + std::cerr << "COUNT: " << BB->getParent()->getFunction ()->getName() << " " + << BB->getNumber() << " " + << count_ins << " " + << count_outs << "\n"; // Clear state used for selection. ExprMap.clear(); @@ -388,6 +407,27 @@ }; } +//Factorize a number using the list of constants +static bool factorize(int v[], int res[], int size, uint64_t c) +{ + bool cont = true; + while (c != 1 && cont) + { + cont = false; + for(int i = 0; i < size; ++i) + { + if (c % v[i] == 0) + { + c /= v[i]; + ++res[i]; + cont=true; + } + } + } + return c == 1; +} + + //Shamelessly adapted from PPC32 // Structure used to return the necessary information to codegen an SDIV as // a multiply. @@ -975,11 +1015,13 @@ if (Address.getOpcode() == ISD::GlobalAddress) { AlphaLowering.restoreGP(BB); Opc = GetSymVersion(Opc); + has_sym = true; BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast(Address)->getGlobal()); } else if (ConstantPoolSDNode *CP = dyn_cast(Address)) { AlphaLowering.restoreGP(BB); Opc = GetSymVersion(Opc); + has_sym = true; BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex()); } else if(Address.getOpcode() == ISD::FrameIndex) { @@ -1050,12 +1092,14 @@ if (Address.getOpcode() == ISD::GlobalAddress) { AlphaLowering.restoreGP(BB); + has_sym = true; BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addGlobalAddress(cast(Address)->getGlobal()); } else if (ConstantPoolSDNode *CP = dyn_cast(N.getOperand(1))) { AlphaLowering.restoreGP(BB); + has_sym = true; BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addConstantPoolIndex(CP->getIndex()); } else if(Address.getOpcode() == ISD::FrameIndex) { @@ -1246,11 +1290,13 @@ if (Address.getOpcode() == ISD::GlobalAddress) { AlphaLowering.restoreGP(BB); Opc = GetSymVersion(Opc); + has_sym = true; BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast(Address)->getGlobal()); } else if (ConstantPoolSDNode *CP = dyn_cast(Address)) { AlphaLowering.restoreGP(BB); Opc = GetSymVersion(Opc); + has_sym = true; BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex()); } else if(Address.getOpcode() == ISD::FrameIndex) { @@ -1267,6 +1313,7 @@ case ISD::GlobalAddress: AlphaLowering.restoreGP(BB); + has_sym = true; BuildMI(BB, Alpha::LOAD_ADDR, 1, Result) .addGlobalAddress(cast(N)->getGlobal()); return Result; @@ -1343,6 +1390,7 @@ //if (GASD->getGlobal()->isExternal()) { //use safe calling convention AlphaLowering.restoreGP(BB); + has_sym = true; BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true); //} else { //use PC relative branch call @@ -1353,6 +1401,7 @@ dyn_cast(N.getOperand(1))) { AlphaLowering.restoreGP(BB); + has_sym = true; BuildMI(BB, Alpha::CALL, 1).addExternalSymbol(ESSDN->getSymbol(), true); } else { //no need to restore GP as we are doing an indirect call @@ -1383,8 +1432,9 @@ case ISD::SIGN_EXTEND_INREG: { - //do SDIV opt for all levels of ints - if (EnableAlphaIDIV && N.getOperand(0).getOpcode() == ISD::SDIV) + //do SDIV opt for all levels of ints if not dividing by a constant + if (EnableAlphaIDIV && N.getOperand(0).getOpcode() == ISD::SDIV + && N.getOperand(0).getOperand(1).getOpcode() != ISD::Constant) { unsigned Tmp4 = MakeReg(MVT::f64); unsigned Tmp5 = MakeReg(MVT::f64); @@ -1483,7 +1533,7 @@ case MVT::i1: Tmp2 = MakeReg(MVT::i64); BuildMI(BB, Alpha::ANDi, 2, Tmp2).addReg(Tmp1).addImm(1); - BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::F31).addReg(Tmp2); + BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::R31).addReg(Tmp2); break; } return Result; @@ -1609,6 +1659,8 @@ case ISD::CopyFromReg: { + ++count_ins; + // Make sure we generate both values. if (Result != notIn) ExprMap[N.getValue(1)] = notIn; // Generate the token @@ -1626,10 +1678,10 @@ //Most of the plain arithmetic and logic share the same form, and the same //constant immediate test - case ISD::OR: + case ISD::XOR: //Match Not if (N.getOperand(1).getOpcode() == ISD::Constant && - cast(N.getOperand(1))->isAllOnesValue()) + cast(N.getOperand(1))->getSignExtended() == -1) { Tmp1 = SelectExpr(N.getOperand(0)); BuildMI(BB, Alpha::ORNOT, 2, Result).addReg(Alpha::R31).addReg(Tmp1); @@ -1637,11 +1689,11 @@ } //Fall through case ISD::AND: - case ISD::XOR: + case ISD::OR: //Check operand(0) == Not - if (N.getOperand(0).getOpcode() == ISD::OR && + if (N.getOperand(0).getOpcode() == ISD::XOR && N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && - cast(N.getOperand(0).getOperand(1))->isAllOnesValue()) + cast(N.getOperand(0).getOperand(1))->getSignExtended() == -1) { switch(opcode) { case ISD::AND: Opc = Alpha::BIC; break; @@ -1654,9 +1706,9 @@ return Result; } //Check operand(1) == Not - if (N.getOperand(1).getOpcode() == ISD::OR && + if (N.getOperand(1).getOpcode() == ISD::XOR && N.getOperand(1).getOperand(1).getOpcode() == ISD::Constant && - cast(N.getOperand(1).getOperand(1))->isAllOnesValue()) + cast(N.getOperand(1).getOperand(1))->getSignExtended() == -1) { switch(opcode) { case ISD::AND: Opc = Alpha::BIC; break; @@ -2044,6 +2096,7 @@ } case ISD::ImplicitDef: + ++count_ins; Select(N.getOperand(0)); BuildMI(BB, Alpha::IDEF, 0, cast(N)->getReg()); return; @@ -2060,6 +2113,7 @@ return; case ISD::CopyToReg: + ++count_outs; Select(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(1)); Tmp2 = cast(N)->getReg(); @@ -2074,6 +2128,7 @@ return; case ISD::RET: + ++count_outs; switch (N.getNumOperands()) { default: std::cerr << N.getNumOperands() << "\n"; @@ -2137,6 +2192,7 @@ { AlphaLowering.restoreGP(BB); Opc = GetSymVersion(Opc); + has_sym = true; BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast(Address)->getGlobal()); } else if(Address.getOpcode() == ISD::FrameIndex) From natebegeman at mac.com Fri Apr 8 16:26:16 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 8 Apr 2005 16:26:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Message-ID: <200504082126.QAA18158@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC64ISelPattern.cpp updated: 1.3 -> 1.4 --- Log message: Match Mac OS X 64 bit calling conventions --- Diffs of the changes: (+46 -116) PPC64ISelPattern.cpp | 162 ++++++++++++++------------------------------------- 1 files changed, 46 insertions(+), 116 deletions(-) Index: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.3 llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.4 --- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.3 Tue Apr 5 19:25:27 2005 +++ llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Fri Apr 8 16:26:05 2005 @@ -101,7 +101,7 @@ // fixed size array of physical args, for the sake of simplicity let the STL // handle tracking them for us. std::vector argVR, argPR, argOp; - unsigned ArgOffset = 24; + unsigned ArgOffset = 48; unsigned GPR_remaining = 8; unsigned FPR_remaining = 13; unsigned GPR_idx = 0, FPR_idx = 0; @@ -115,11 +115,10 @@ }; // Add DAG nodes to load the arguments... On entry to a function on PPC, - // the arguments start at offset 24, although they are likely to be passed + // the arguments start at offset 48, although they are likely to be passed // in registers. for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { SDOperand newroot, argt; - unsigned ObjSize; bool needsLoad = false; MVT::ValueType ObjectVT = getValueType(I->getType()); @@ -129,35 +128,19 @@ case MVT::i8: case MVT::i16: case MVT::i32: - ObjSize = 4; + case MVT::i64: if (GPR_remaining > 0) { BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); argt = newroot = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot()); - if (ObjectVT != MVT::i32) + if (ObjectVT != MVT::i64) argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, newroot); } else { needsLoad = true; } break; - case MVT::i64: ObjSize = 8; - // FIXME: can split 64b load between reg/mem if it is last arg in regs - if (GPR_remaining > 1) { - BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); - BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx+1]); - // Copy the extracted halves into the virtual registers - SDOperand argHi = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, - DAG.getRoot()); - SDOperand argLo = DAG.getCopyFromReg(GPR[GPR_idx+1], MVT::i32, argHi); - // Build the outgoing arg thingy - argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi); - newroot = argLo; - } else { - needsLoad = true; - } - break; - case MVT::f32: ObjSize = 4; - case MVT::f64: ObjSize = 8; + case MVT::f32: + case MVT::f64: if (FPR_remaining > 0) { BuildMI(&BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]); argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT, @@ -174,23 +157,30 @@ // that we ran out of physical registers of the appropriate type if (needsLoad) { unsigned SubregOffset = 0; - if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3; - if (ObjectVT == MVT::i16) SubregOffset = 2; - int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); - FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, - DAG.getConstant(SubregOffset, MVT::i32)); + switch (ObjectVT) { + default: assert(0 && "Unhandled argument type!"); + case MVT::i1: + case MVT::i8: SubregOffset = 7; break; + case MVT::i16: SubregOffset = 6; break; + case MVT::i32: + case MVT::f32: SubregOffset = 4; break; + case MVT::i64: + case MVT::f64: SubregOffset = 0; break; + } + int FI = MFI->CreateFixedObject(8, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64); + FIN = DAG.getNode(ISD::ADD, MVT::i64, FIN, + DAG.getConstant(SubregOffset, MVT::i64)); argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN); } // Every 4 bytes of argument space consumes one of the GPRs available for // argument passing. if (GPR_remaining > 0) { - unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1; - GPR_remaining -= delta; - GPR_idx += delta; + --GPR_remaining; + ++GPR_idx; } - ArgOffset += ObjSize; + ArgOffset += 8; DAG.setRoot(newroot.getValue(1)); ArgValues.push_back(argt); @@ -199,20 +189,20 @@ // If the function takes variable number of arguments, make a frame index for // the start of the first vararg value... for expansion of llvm.va_start. if (F.isVarArg()) { - VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); - SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); + VarArgsFrameIndex = MFI->CreateFixedObject(8, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); // If this function is vararg, store any remaining integer argument regs // to their spots on the stack so that they may be loaded by deferencing the // result of va_next. std::vector MemOps; for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) { BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); - SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot()); + SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i64, DAG.getRoot()); SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), Val, FIN); MemOps.push_back(Store); - // Increment the address by four for the next argument to store - SDOperand PtrOff = DAG.getConstant(4, getPointerTy()); + // Increment the address by eight for the next argument to store + SDOperand PtrOff = DAG.getConstant(8, getPointerTy()); FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff); } DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps)); @@ -231,31 +221,17 @@ // Count how many bytes are to be pushed on the stack, including the linkage // area, and parameter passing area. - unsigned NumBytes = 24; + unsigned NumBytes = 48; if (Args.empty()) { Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain, DAG.getConstant(NumBytes, getPointerTy())); } else { - for (unsigned i = 0, e = Args.size(); i != e; ++i) - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unknown value type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::f32: - NumBytes += 4; - break; - case MVT::i64: - case MVT::f64: - NumBytes += 8; - break; - } + NumBytes = 8 * Args.size(); // All arguments are rounded up to 8 bytes - // Just to be safe, we'll always reserve the full 24 bytes of linkage area - // plus 32 bytes of argument space in case any called code gets funky on us. - if (NumBytes < 56) NumBytes = 56; + // Just to be safe, we'll always reserve the full 48 bytes of linkage area + // plus 64 bytes of argument space in case any called code gets funky on us. + if (NumBytes < 112) NumBytes = 112; // Adjust the stack pointer for the new arguments... // These operations are automatically eliminated by the prolog/epilog pass @@ -272,7 +248,7 @@ // memory. Also, if this is a vararg function, floating point operations // must be stored to our stack, and loaded into integer regs as well, if // any integer regs are available for argument passing. - unsigned ArgOffset = 24; + unsigned ArgOffset = 48; unsigned GPR_remaining = 8; unsigned FPR_remaining = 13; @@ -289,43 +265,18 @@ case MVT::i1: case MVT::i8: case MVT::i16: - // Promote the integer to 32 bits. If the input type is signed use a + case MVT::i32: + // Promote the integer to 64 bits. If the input type is signed use a // sign extend, otherwise use a zero extend. if (Args[i].second->isSigned()) - Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); + Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first); else - Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); + Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first); // FALL THROUGH - case MVT::i32: - if (GPR_remaining > 0) { - args_to_use.push_back(Args[i].first); - --GPR_remaining; - } else { - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff)); - } - ArgOffset += 4; - break; case MVT::i64: - // If we have one free GPR left, we can place the upper half of the i64 - // in it, and store the other half to the stack. If we have two or more - // free GPRs, then we can pass both halves of the i64 in registers. if (GPR_remaining > 0) { - SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(1, MVT::i32)); - SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(0, MVT::i32)); - args_to_use.push_back(Hi); + args_to_use.push_back(Args[i].first); --GPR_remaining; - if (GPR_remaining > 0) { - args_to_use.push_back(Lo); - --GPR_remaining; - } else { - SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Lo, PtrOff)); - } } else { MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, Args[i].first, PtrOff)); @@ -343,29 +294,16 @@ MemOps.push_back(Store); // Float varargs are always shadowed in available integer registers if (GPR_remaining > 0) { - SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff); - MemOps.push_back(Load); - args_to_use.push_back(Load); - --GPR_remaining; - } - if (GPR_remaining > 0 && MVT::f64 == ArgVT) { - SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); - SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff); + SDOperand Load = DAG.getLoad(MVT::i64, Store, PtrOff); MemOps.push_back(Load); args_to_use.push_back(Load); --GPR_remaining; } } else { // If we have any FPRs remaining, we may also have GPRs remaining. - // Args passed in FPRs consume either 1 (f32) or 2 (f64) available - // GPRs. + // Args passed in FPRs also consume an available GPR. if (GPR_remaining > 0) { - args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); - --GPR_remaining; - } - if (GPR_remaining > 0 && MVT::f64 == ArgVT) { - args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); + args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i64)); --GPR_remaining; } } @@ -373,7 +311,7 @@ MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, Args[i].first, PtrOff)); } - ArgOffset += (ArgVT == MVT::f32) ? 4 : 8; + ArgOffset += 8; break; } } @@ -398,7 +336,7 @@ std::pair PPC64TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { //vastart just returns the address of the VarArgsFrameIndex slot. - return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32), Chain); + return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain); } std::pair PPC64TargetLowering:: @@ -409,16 +347,8 @@ if (!isVANext) { Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), VAList); } else { - unsigned Amt; - if (ArgVT == MVT::i32 || ArgVT == MVT::f32) - Amt = 4; - else { - assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && - "Other types should have been promoted for varargs!"); - Amt = 8; - } Result = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, - DAG.getConstant(Amt, VAList.getValueType())); + DAG.getConstant(8, VAList.getValueType())); } return std::make_pair(Result, Chain); } @@ -596,7 +526,7 @@ /// getConstDouble - Loads a floating point value into a register, via the /// Constant Pool. Optionally takes a register in which to load the value. unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) { - unsigned Tmp1 = MakeReg(MVT::i32); + unsigned Tmp1 = MakeReg(MVT::i64); if (0 == Result) Result = MakeReg(MVT::f64); MachineConstantPool *CP = BB->getParent()->getConstantPool(); ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, doubleVal); From lattner at cs.uiuc.edu Fri Apr 8 16:31:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 16:31:46 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200504082131.j38LVkOQ003706@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.29 -> 1.30 --- Log message: fix this method for 64-bit constants --- Diffs of the changes: (+3 -1) SelectionDAGNodes.h | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.29 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.30 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.29 Tue Apr 5 23:21:29 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Fri Apr 8 16:31:29 2005 @@ -605,7 +605,9 @@ bool isNullValue() const { return Value == 0; } bool isAllOnesValue() const { - return Value == (1ULL << MVT::getSizeInBits(getValueType(0)))-1; + int NumBits = MVT::getSizeInBits(getValueType(0)); + if (NumBits == 64) return Value+1 == 0; + return Value == (1ULL << NumBits)-1; } static bool classof(const ConstantSDNode *) { return true; } From natebegeman at mac.com Fri Apr 8 18:45:12 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 8 Apr 2005 18:45:12 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Message-ID: <200504082345.SAA18648@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC64ISelPattern.cpp updated: 1.4 -> 1.5 --- Log message: Fix 64b shifts --- Diffs of the changes: (+13 -26) PPC64ISelPattern.cpp | 39 +++++++++++++-------------------------- 1 files changed, 13 insertions(+), 26 deletions(-) Index: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.4 llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.5 --- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.4 Fri Apr 8 16:26:05 2005 +++ llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Fri Apr 8 18:45:01 2005 @@ -985,7 +985,7 @@ BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) .addGlobalAddress(GV); if (GV->hasWeakLinkage() || GV->isExternal()) { - BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1); + BuildMI(BB, PPC::LD, 2, Result).addGlobalAddress(GV).addReg(Tmp1); } else { BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp1).addGlobalAddress(GV); } @@ -1171,35 +1171,35 @@ case ISD::SHL: Tmp1 = SelectExpr(N.getOperand(0)); if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { - Tmp2 = CN->getValue() & 0x1F; - BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(Tmp2).addImm(0) - .addImm(31-Tmp2); + Tmp2 = CN->getValue() & 0x3F; + BuildMI(BB, PPC::RLDICR, 3, Result).addReg(Tmp1).addImm(Tmp2) + .addImm(63-Tmp2); } else { Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::SLW, 2, Result).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, PPC::SLD, 2, Result).addReg(Tmp1).addReg(Tmp2); } return Result; case ISD::SRL: Tmp1 = SelectExpr(N.getOperand(0)); if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { - Tmp2 = CN->getValue() & 0x1F; - BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(32-Tmp2) - .addImm(Tmp2).addImm(31); + Tmp2 = CN->getValue() & 0x3F; + BuildMI(BB, PPC::RLDICL, 3, Result).addReg(Tmp1).addImm(64-Tmp2) + .addImm(Tmp2); } else { Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::SRW, 2, Result).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, PPC::SRD, 2, Result).addReg(Tmp1).addReg(Tmp2); } return Result; case ISD::SRA: Tmp1 = SelectExpr(N.getOperand(0)); if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { - Tmp2 = CN->getValue() & 0x1F; - BuildMI(BB, PPC::SRAWI, 2, Result).addReg(Tmp1).addImm(Tmp2); + Tmp2 = CN->getValue() & 0x3F; + BuildMI(BB, PPC::SRADI, 2, Result).addReg(Tmp1).addImm(Tmp2); } else { Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::SRAW, 2, Result).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, PPC::SRAD, 2, Result).addReg(Tmp1).addReg(Tmp2); } return Result; @@ -1325,7 +1325,7 @@ if (3 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) { Tmp1 = MakeReg(MVT::i64); Tmp2 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3); + BuildMI(BB, PPC::SRADI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3); BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1); return Result; } @@ -1335,19 +1335,6 @@ BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; - case ISD::UREM: - case ISD::SREM: { - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - Tmp3 = MakeReg(MVT::i64); - unsigned Tmp4 = MakeReg(MVT::i64); - Opc = (ISD::UREM == opcode) ? PPC::DIVDU : PPC::DIVD; - BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); - BuildMI(BB, PPC::MULLD, 2, Tmp4).addReg(Tmp3).addReg(Tmp2); - BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp4).addReg(Tmp1); - return Result; - } - case ISD::FP_TO_UINT: case ISD::FP_TO_SINT: { Tmp1 = SelectExpr(N.getOperand(0)); From lattner at cs.uiuc.edu Fri Apr 8 22:03:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 22:03:03 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504090303.j39333sN006037@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.63 -> 1.64 --- Log message: canonicalize a bunch of operations involving fneg --- Diffs of the changes: (+21 -0) SelectionDAG.cpp | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.63 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.64 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.63 Thu Apr 7 14:43:53 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Apr 8 22:02:46 2005 @@ -565,6 +565,8 @@ if (ConstantFPSDNode *C = dyn_cast(Operand.Val)) switch (Opcode) { + case ISD::FNEG: + return getConstantFP(-C->getValue(), VT); case ISD::FP_ROUND: case ISD::FP_EXTEND: return getConstantFP(C->getValue(), VT); @@ -602,6 +604,17 @@ return Operand.Val->getOperand(0); } break; + case ISD::FNEG: + if (OpOpcode == ISD::SUB) // -(X-Y) -> (Y-X) + return getNode(ISD::SUB, VT, Operand.Val->getOperand(1), + Operand.Val->getOperand(0)); + if (OpOpcode == ISD::FNEG) // --X -> X + return Operand.Val->getOperand(0); + break; + case ISD::FABS: + if (OpOpcode == ISD::FNEG) // abs(-X) -> abs(X) + return getNode(ISD::FABS, VT, Operand.Val->getOperand(0)); + break; } SDNode *&N = UnaryOps[std::make_pair(Opcode, std::make_pair(Operand, VT))]; @@ -859,6 +872,12 @@ case ISD::XOR: if (N1 == N2) return getConstant(0, VT); // xor X, Y -> 0 break; + case ISD::ADD: + if (N2.getOpcode() == ISD::FNEG) // (A+ (-B) -> A-B + return getNode(ISD::SUB, VT, N1, N2.getOperand(0)); + if (N1.getOpcode() == ISD::FNEG) // ((-A)+B) -> B-A + return getNode(ISD::SUB, VT, N2, N1.getOperand(0)); + break; case ISD::SUB: if (N1.getOpcode() == ISD::ADD) { if (N1.Val->getOperand(0) == N2) @@ -866,6 +885,8 @@ if (N1.Val->getOperand(1) == N2) return N1.Val->getOperand(0); // (A+B)-B == A } + if (N2.getOpcode() == ISD::FNEG) // (A- (-B) -> A+B + return getNode(ISD::ADD, VT, N1, N2.getOperand(0)); break; } From natebegeman at mac.com Fri Apr 8 22:06:02 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 8 Apr 2005 22:06:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PPC64ISelPattern.cpp Message-ID: <200504090306.WAA19342@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.52 -> 1.53 PPC64ISelPattern.cpp updated: 1.5 -> 1.6 --- Log message: 64b: Expand S/UREM 32b: No longer pattern match fneg(fsub(fmul)) as fnmsub Pattern match fsub a, mul(b, c) as fnmsub Pattern match fadd a, mul(b, c) as fmadd Those changes speed up hydro2d by 2.5%, distray by 6%, and scimark by 8% --- Diffs of the changes: (+31 -7) PPC32ISelPattern.cpp | 34 +++++++++++++++++++++++++++------- PPC64ISelPattern.cpp | 4 ++++ 2 files changed, 31 insertions(+), 7 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.52 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.53 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.52 Thu Apr 7 15:30:01 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Fri Apr 8 22:05:51 2005 @@ -1117,15 +1117,15 @@ Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS; BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); } else if (!NoExcessFPPrecision && - ISD::SUB == N.getOperand(0).getOpcode() && + ISD::ADD == N.getOperand(0).getOpcode() && N.getOperand(0).Val->hasOneUse() && - ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && - N.getOperand(0).getOperand(0).Val->hasOneUse()) { + ISD::MUL == N.getOperand(0).getOperand(1).getOpcode() && + N.getOperand(0).getOperand(1).Val->hasOneUse()) { ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(0).getOperand(1)); - Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS; + Tmp1 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0).getOperand(0)); + Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS; BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); } else if (ISD::FABS == N.getOperand(0).getOpcode()) { Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); @@ -1181,6 +1181,16 @@ BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; } + if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL && + N.getOperand(1).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(1).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0)); + Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS; Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); @@ -1198,6 +1208,16 @@ BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); return Result; } + if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL && + N.getOperand(1).Val->hasOneUse()) { + ++FusedFP; // Statistic + Tmp1 = SelectExpr(N.getOperand(1).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1).getOperand(1)); + Tmp3 = SelectExpr(N.getOperand(0)); + Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS; + BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); + return Result; + } Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS; Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); Index: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.5 llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.6 --- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.5 Fri Apr 8 18:45:01 2005 +++ llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Fri Apr 8 22:05:51 2005 @@ -55,6 +55,10 @@ setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand); setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); + // PowerPC has no SREM/UREM instructions + setOperationAction(ISD::SREM, MVT::i64, Expand); + setOperationAction(ISD::UREM, MVT::i64, Expand); + setShiftAmountFlavor(Extend); // shl X, 32 == 0 addLegalFPImmediate(+0.0); // Necessary for FSEL addLegalFPImmediate(-0.0); // From lattner at cs.uiuc.edu Fri Apr 8 22:22:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 22:22:06 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200504090322.j393M6Je010154@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.30 -> 1.31 --- Log message: Add a new node --- Diffs of the changes: (+7 -0) SelectionDAGNodes.h | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.30 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.31 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.30 Fri Apr 8 16:31:29 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Fri Apr 8 22:21:50 2005 @@ -216,6 +216,13 @@ // to if the condition is true. BRCOND, + // BRCONDTWOWAY - Two-way conditional branch. The first operand is the + // chain, the second is the condition, the third is the block to branch to + // if true, and the forth is the block to branch to if false. Targets + // usually do not implement this, preferring to have legalize demote the + // operation to BRCOND/BR pairs when necessary. + BRCONDTWOWAY, + // RET - Return from function. The first operand is the chain, // and any subsequent operands are the return values for the // function. This operation can have variable number of operands. From lattner at cs.uiuc.edu Fri Apr 8 22:22:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 22:22:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PPC64ISelPattern.cpp Message-ID: <200504090322.j393Mijr010183@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.53 -> 1.54 PPC64ISelPattern.cpp updated: 1.6 -> 1.7 --- Log message: This target does not yet support ISD::BRCONDTWOWAY --- Diffs of the changes: (+2 -0) PPC32ISelPattern.cpp | 1 + PPC64ISelPattern.cpp | 1 + 2 files changed, 2 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.53 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.54 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.53 Fri Apr 8 22:05:51 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Fri Apr 8 22:22:30 2005 @@ -49,6 +49,7 @@ addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass); // PowerPC has no intrinsics for these particular operations + setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); setOperationAction(ISD::MEMSET, MVT::Other, Expand); setOperationAction(ISD::MEMCPY, MVT::Other, Expand); Index: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.6 llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.7 --- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.6 Fri Apr 8 22:05:51 2005 +++ llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Fri Apr 8 22:22:30 2005 @@ -47,6 +47,7 @@ addRegisterClass(MVT::f64, PPC64::FPRCRegisterClass); // PowerPC has no intrinsics for these particular operations + setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); setOperationAction(ISD::MEMSET, MVT::Other, Expand); setOperationAction(ISD::MEMCPY, MVT::Other, Expand); From lattner at cs.uiuc.edu Fri Apr 8 22:22:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 22:22:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200504090322.j393MouK010193@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.101 -> 1.102 --- Log message: This target does not support/want ISD::BRCONDTWOWAY --- Diffs of the changes: (+1 -0) X86ISelPattern.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.101 llvm/lib/Target/X86/X86ISelPattern.cpp:1.102 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.101 Thu Apr 7 14:41:46 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Fri Apr 8 22:22:37 2005 @@ -56,6 +56,7 @@ // well. /**/ addRegisterClass(MVT::i1, X86::R8RegisterClass); + setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); setOperationAction(ISD::ZERO_EXTEND_INREG, MVT::i16 , Expand); From lattner at cs.uiuc.edu Fri Apr 8 22:23:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 22:23:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200504090323.j393N6uJ010201@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.90 -> 1.91 --- Log message: This target does not support/want ISD::BRCONDTWOWAY --- Diffs of the changes: (+1 -0) AlphaISelPattern.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.90 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.91 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.90 Fri Apr 8 12:28:49 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Fri Apr 8 22:22:22 2005 @@ -62,6 +62,7 @@ addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass); addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass); + setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote); setOperationAction(ISD::EXTLOAD , MVT::f32 , Promote); From lattner at cs.uiuc.edu Fri Apr 8 22:23:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 22:23:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200504090323.j393N8P2010207@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.14 -> 1.15 --- Log message: This target does not support/want ISD::BRCONDTWOWAY --- Diffs of the changes: (+1 -0) IA64ISelPattern.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.14 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.15 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.14 Fri Apr 8 05:01:48 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Fri Apr 8 22:22:24 2005 @@ -55,6 +55,7 @@ // register class for predicate registers addRegisterClass(MVT::i1, IA64::PRRegisterClass); + setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); setSetCCResultType(MVT::i1); From lattner at cs.uiuc.edu Fri Apr 8 22:27:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 22:27:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504090327.j393RgSA010225@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.64 -> 1.65 --- Log message: print and fold BRCONDTWOWAY correctly --- Diffs of the changes: (+25 -11) SelectionDAG.cpp | 36 +++++++++++++++++++++++++----------- 1 files changed, 25 insertions(+), 11 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.64 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.65 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.64 Fri Apr 8 22:02:46 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Apr 8 22:27:28 2005 @@ -992,18 +992,31 @@ case 1: return getNode(Opcode, VT, Children[0]); case 2: return getNode(Opcode, VT, Children[0], Children[1]); case 3: return getNode(Opcode, VT, Children[0], Children[1], Children[2]); - default: - // FIXME: MEMOIZE!! - SDNode *N = new SDNode(Opcode, Children); - if (Opcode != ISD::ADD_PARTS && Opcode != ISD::SUB_PARTS) { - N->setValueTypes(VT); - } else { - std::vector V(N->getNumOperands()/2, VT); - N->setValueTypes(V); - } - AllNodes.push_back(N); - return SDOperand(N, 0); + default: break; + } + + ConstantSDNode *N1C = dyn_cast(Children[1].Val); + switch (Opcode) { + default: break; + case ISD::BRCONDTWOWAY: + if (N1C) + if (N1C->getValue()) // Unconditional branch to true dest. + return getNode(ISD::BR, MVT::Other, Children[0], Children[2]); + else // Unconditional branch to false dest. + return getNode(ISD::BR, MVT::Other, Children[0], Children[3]); + break; } + + // FIXME: MEMOIZE!! + SDNode *N = new SDNode(Opcode, Children); + if (Opcode != ISD::ADD_PARTS && Opcode != ISD::SUB_PARTS) { + N->setValueTypes(VT); + } else { + std::vector V(N->getNumOperands()/2, VT); + N->setValueTypes(V); + } + AllNodes.push_back(N); + return SDOperand(N, 0); } SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1, @@ -1243,6 +1256,7 @@ // Control flow instructions case ISD::BR: return "br"; case ISD::BRCOND: return "brcond"; + case ISD::BRCONDTWOWAY: return "brcondtwoway"; case ISD::RET: return "ret"; case ISD::CALL: return "call"; case ISD::ADJCALLSTACKDOWN: return "adjcallstackdown"; From lattner at cs.uiuc.edu Fri Apr 8 22:30:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 22:30:33 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200504090330.j393UXlG010557@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.75 -> 1.76 --- Log message: Legalize BRCONDTWOWAY into a BRCOND/BR pair if a target doesn't support it. --- Diffs of the changes: (+33 -0) LegalizeDAG.cpp | 33 +++++++++++++++++++++++++++++++++ 1 files changed, 33 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.75 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.76 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.75 Wed Apr 6 16:13:14 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Apr 8 22:30:19 2005 @@ -391,6 +391,39 @@ Result = DAG.getNode(ISD::BRCOND, MVT::Other, Tmp1, Tmp2, Node->getOperand(2)); break; + case ISD::BRCONDTWOWAY: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + switch (getTypeAction(Node->getOperand(1).getValueType())) { + case Expand: assert(0 && "It's impossible to expand bools"); + case Legal: + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the condition. + break; + case Promote: + Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the condition. + break; + } + // If this target does not support BRCONDTWOWAY, lower it to a BRCOND/BR + // pair. + switch (TLI.getOperationAction(ISD::BRCONDTWOWAY, MVT::Other)) { + case TargetLowering::Promote: + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) { + std::vector Ops; + Ops.push_back(Tmp1); + Ops.push_back(Tmp2); + Ops.push_back(Node->getOperand(2)); + Ops.push_back(Node->getOperand(3)); + Result = DAG.getNode(ISD::BRCONDTWOWAY, MVT::Other, Ops); + } + break; + case TargetLowering::Expand: + Result = DAG.getNode(ISD::BRCOND, MVT::Other, Tmp1, Tmp2, + Node->getOperand(2)); + Result = DAG.getNode(ISD::BR, MVT::Other, Result, Node->getOperand(3)); + break; + } + break; case ISD::LOAD: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. From lattner at cs.uiuc.edu Fri Apr 8 22:30:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 22:30:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200504090330.j393UhkG010566@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.39 -> 1.40 --- Log message: Emit BRCONDTWOWAY when possible. --- Diffs of the changes: (+6 -7) SelectionDAGISel.cpp | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.39 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.40 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.39 Fri Apr 1 23:26:53 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Apr 8 22:30:29 2005 @@ -430,7 +430,6 @@ MachineBasicBlock *Succ1MBB = FuncInfo.MBBMap[I.getSuccessor(1)]; SDOperand Cond = getValue(I.getCondition()); - if (Succ1MBB == NextBlock) { // If the condition is false, fall through. This means we should branch // if the condition is true to Succ #0. @@ -444,12 +443,12 @@ DAG.setRoot(DAG.getNode(ISD::BRCOND, MVT::Other, getRoot(), Cond, DAG.getBasicBlock(Succ1MBB))); } else { - // Neither edge is a fall through. If the comparison is true, jump to - // Succ#0, otherwise branch unconditionally to succ #1. - DAG.setRoot(DAG.getNode(ISD::BRCOND, MVT::Other, getRoot(), - Cond, DAG.getBasicBlock(Succ0MBB))); - DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(), - DAG.getBasicBlock(Succ1MBB))); + std::vector Ops; + Ops.push_back(getRoot()); + Ops.push_back(Cond); + Ops.push_back(DAG.getBasicBlock(Succ0MBB)); + Ops.push_back(DAG.getBasicBlock(Succ1MBB)); + DAG.setRoot(DAG.getNode(ISD::BRCONDTWOWAY, MVT::Other, Ops)); } } } From lattner at cs.uiuc.edu Fri Apr 8 23:01:45 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 23:01:45 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/fma.ll Message-ID: <200504090401.j3941jNn010895@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: fma.ll added (r1.1) --- Log message: add a partial test for the fma operations that ppc supports. I'm sure I'm missing some and not all of these match yet, but I'm sure that Nate will clean up my mess :) --- Diffs of the changes: (+30 -0) fma.ll | 30 ++++++++++++++++++++++++++++++ 1 files changed, 30 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/fma.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/fma.ll:1.1 *** /dev/null Fri Apr 8 23:01:42 2005 --- llvm/test/Regression/CodeGen/PowerPC/fma.ll Fri Apr 8 23:01:32 2005 *************** *** 0 **** --- 1,30 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 -enable-ppc-pattern-isel | grep 'fn\?madd\|fn\?msub' | wc -l | grep 5 + + double %test_FMADD(double %A, double %B, double %C) { + %D = mul double %A, %B + %E = add double %D, %C + ret double %E + } + double %test_FMSUB(double %A, double %B, double %C) { + %D = mul double %A, %B + %E = sub double %D, %C + ret double %E + } + double %test_FNMADD1(double %A, double %B, double %C) { + %D = mul double %A, %B + %E = sub double %D, %C + %F = sub double -0.0, %E + ret double %F + } + double %test_FNMADD2(double %A, double %B, double %C) { + %D = mul double %A, %B + %E = add double %D, %C + %F = sub double -0.0, %E + ret double %F + } + double %test_FNMADD3(double %A, double %B, double %C) { + %D = mul double %A, %B + %E = add double %C, %D + %F = sub double -0.0, %E + ret double %F + } From lattner at cs.uiuc.edu Fri Apr 8 23:03:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 23:03:29 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/fnabs.ll Message-ID: <200504090403.j3943TCQ010923@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: fnabs.ll added (r1.1) --- Log message: add a test for fnabs --- Diffs of the changes: (+11 -0) fnabs.ll | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/fnabs.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/fnabs.ll:1.1 *** /dev/null Fri Apr 8 23:03:26 2005 --- llvm/test/Regression/CodeGen/PowerPC/fnabs.ll Fri Apr 8 23:03:16 2005 *************** *** 0 **** --- 1,11 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 -enable-ppc-pattern-isel | grep fnabs + + declare double %fabs(double) + + implementation + + double %test(double %X) { + %Y = call double %fabs(double %X) + %Z = sub double -0.0, %Y + ret double %Z + } From lattner at cs.uiuc.edu Fri Apr 8 23:34:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 23:34:51 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200504090434.j394Ypi9011321@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.90 -> 1.91 --- Log message: The negation part of fabs should use -0.0 for FP values. --- Diffs of the changes: (+4 -1) llvm-expand.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.90 llvm-gcc/gcc/llvm-expand.c:1.91 --- llvm-gcc/gcc/llvm-expand.c:1.90 Fri Mar 11 00:12:27 2005 +++ llvm-gcc/gcc/llvm-expand.c Fri Apr 8 23:34:34 2005 @@ -6603,7 +6603,10 @@ } case ABS_EXPR: { op0 = llvm_expand_expr(Fn, TREE_OPERAND(exp, 0), 0); - op1 = llvm_constant_get_null(op0->Ty); + if (!llvm_type_is_fp(op1->Ty)) + op1 = llvm_constant_get_null(op0->Ty); + else + op1 = llvm_constant_new(op1->Ty, "-0.0"); Result = llvm_expand_minmaxabs_expr(Fn, exp, op0, op1); break; } From lattner at cs.uiuc.edu Fri Apr 8 23:41:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 23:41:42 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200504090441.j394fg91012716@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.91 -> 1.92 --- Log message: fix a bug in previous checkin --- Diffs of the changes: (+1 -1) llvm-expand.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.91 llvm-gcc/gcc/llvm-expand.c:1.92 --- llvm-gcc/gcc/llvm-expand.c:1.91 Fri Apr 8 23:34:34 2005 +++ llvm-gcc/gcc/llvm-expand.c Fri Apr 8 23:41:26 2005 @@ -6606,7 +6606,7 @@ if (!llvm_type_is_fp(op1->Ty)) op1 = llvm_constant_get_null(op0->Ty); else - op1 = llvm_constant_new(op1->Ty, "-0.0"); + op1 = llvm_constant_new(op0->Ty, "-0.0"); Result = llvm_expand_minmaxabs_expr(Fn, exp, op0, op1); break; } From lattner at cs.uiuc.edu Fri Apr 8 23:43:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 23:43:11 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200504090443.j394hBS1012894@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.92 -> 1.93 --- Log message: ARG! really fix the bugs! --- Diffs of the changes: (+1 -1) llvm-expand.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.92 llvm-gcc/gcc/llvm-expand.c:1.93 --- llvm-gcc/gcc/llvm-expand.c:1.92 Fri Apr 8 23:41:26 2005 +++ llvm-gcc/gcc/llvm-expand.c Fri Apr 8 23:42:55 2005 @@ -6603,7 +6603,7 @@ } case ABS_EXPR: { op0 = llvm_expand_expr(Fn, TREE_OPERAND(exp, 0), 0); - if (!llvm_type_is_fp(op1->Ty)) + if (!llvm_type_is_fp(op0->Ty)) op1 = llvm_constant_get_null(op0->Ty); else op1 = llvm_constant_new(op0->Ty, "-0.0"); From lattner at cs.uiuc.edu Fri Apr 8 23:55:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 8 Apr 2005 23:55:30 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/fabs.ll Message-ID: <200504090455.j394tUdq014278@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: fabs.ll updated: 1.2 -> 1.3 --- Log message: make this test more interesting --- Diffs of the changes: (+8 -1) fabs.ll | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/X86/fabs.ll diff -u llvm/test/Regression/CodeGen/X86/fabs.ll:1.2 llvm/test/Regression/CodeGen/X86/fabs.ll:1.3 --- llvm/test/Regression/CodeGen/X86/fabs.ll:1.2 Fri Apr 1 23:40:03 2005 +++ llvm/test/Regression/CodeGen/X86/fabs.ll Fri Apr 8 23:55:14 2005 @@ -1,5 +1,5 @@ ; Make sure this testcase codegens to the fabs instruction, not a call to fabsf -; RUN: llvm-as < %s | llc -march=x86 -disable-pattern-isel=0 | grep 'fabs$' +; RUN: llvm-as < %s | llc -march=x86 -disable-pattern-isel=0 | grep 'fabs$' | wc -l | grep 2 declare float %fabsf(float) @@ -8,3 +8,10 @@ ret float %Y } +double %fabstest2(double %X) { + %Y = setge double %X, -0.0 + %Z = sub double -0.0, %X + %Q = select bool %Y, double %X, double %Z + ret double %Q +} + From lattner at cs.uiuc.edu Sat Apr 9 00:16:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 00:16:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504090516.j395G936019857@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.65 -> 1.66 --- Log message: recognize some patterns as fabs operations, so that fabs at the source level is deconstructed then reconstructed here. This catches 19 fabs's in 177.mesa 9 in 168.wupwise, 5 in 171.swim, 3 in 172.mgrid, and 14 in 173.applu out of specfp2000. This allows the X86 code generator to make MUCH better code than before for each of these and saves one instr on ppc. This depends on the previous CFE patch to expose these correctly. --- Diffs of the changes: (+21 -0) SelectionDAG.cpp | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.65 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.66 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.65 Fri Apr 8 22:27:28 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Apr 9 00:15:53 2005 @@ -952,6 +952,27 @@ } } + // If this is a selectcc, check to see if we can simplify the result. + if (SetCCSDNode *SetCC = dyn_cast(N1)) { + if (ConstantFPSDNode *CFP = + dyn_cast(SetCC->getOperand(1))) + if (CFP->getValue() == 0.0) { // Allow either -0.0 or 0.0 + // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs + if ((SetCC->getCondition() == ISD::SETGE || + SetCC->getCondition() == ISD::SETGT) && + N2 == SetCC->getOperand(0) && N3.getOpcode() == ISD::FNEG && + N3.getOperand(0) == N2) + return getNode(ISD::FABS, VT, N2); + + // select (setl[te] X, +/-0.0), fneg(X), X -> fabs + if ((SetCC->getCondition() == ISD::SETLT || + SetCC->getCondition() == ISD::SETLE) && + N3 == SetCC->getOperand(0) && N2.getOpcode() == ISD::FNEG && + N2.getOperand(0) == N3) + return getNode(ISD::FABS, VT, N3); + } + + } break; case ISD::BRCOND: if (N2C) From lattner at cs.uiuc.edu Sat Apr 9 01:26:46 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 01:26:46 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/SparcV9/2005-05-09-GEP-Crash.ll Message-ID: <200504090626.j396Qk1v021600@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/SparcV9: 2005-05-09-GEP-Crash.ll added (r1.1) --- Log message: New testcase that the sparc backend crashes on --- Diffs of the changes: (+12 -0) 2005-05-09-GEP-Crash.ll | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/test/Regression/CodeGen/SparcV9/2005-05-09-GEP-Crash.ll diff -c /dev/null llvm/test/Regression/CodeGen/SparcV9/2005-05-09-GEP-Crash.ll:1.1 *** /dev/null Sat Apr 9 01:26:39 2005 --- llvm/test/Regression/CodeGen/SparcV9/2005-05-09-GEP-Crash.ll Sat Apr 9 01:26:27 2005 *************** *** 0 **** --- 1,12 ---- + ; RUN: llvm-as < %s | llc -march=sparcv9 + + + %x_ = external global { [2530944 x double], [2197000 x double], [2530944 x double], [4 x double], [4 x double], [7 x long], [7 x long] } + + implementation + + void %norm2u3_() { + entry: + %tmp.47 = getelementptr [2530944 x double]* cast (double* getelementptr ([2530944 x double]* getelementptr ({ [2530944 x double], [2197000 x double], [2530944 x double], [4 x double], [4 x double], [7 x long], [7 x long] }* %x_, long 0, uint 0), long 1, long 2197000) to [2530944 x double]*), long 0, long 0 + ret void + } From lattner at cs.uiuc.edu Sat Apr 9 01:27:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 01:27:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp Message-ID: <200504090627.j396RRUA021612@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9BurgISel.cpp updated: 1.15 -> 1.16 --- Log message: Fix CodeGen/SparcV9/2005-05-09-GEP-Crash.ll a crash on some specfp program lets hope this doesn't break other programs with induced entropy --- Diffs of the changes: (+1 -1) SparcV9BurgISel.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp diff -u llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.15 llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.16 --- llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp:1.15 Sun Jan 23 19:40:18 2005 +++ llvm/lib/Target/SparcV9/SparcV9BurgISel.cpp Sat Apr 9 01:27:14 2005 @@ -1738,7 +1738,7 @@ // in this and any preceding GetElemPtr instructions. bool foldedGEPs = false; bool leadingNonZeroIdx = gepI && ! IsZero(*gepI->idx_begin()); - if (allConstantIndices) + if (allConstantIndices && !leadingNonZeroIdx) if (Value* newPtr = FoldGetElemChain(ptrChild, idxVec, leadingNonZeroIdx)) { ptrVal = newPtr; foldedGEPs = true; From natebegeman at mac.com Sat Apr 9 03:30:10 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 9 Apr 2005 03:30:10 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/fma.ll Message-ID: <200504090830.DAA05098@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: fma.ll updated: 1.1 -> 1.2 --- Log message: Add cases to cover the rest of the patterns we should be matching --- Diffs of the changes: (+16 -6) fma.ll | 22 ++++++++++++++++------ 1 files changed, 16 insertions(+), 6 deletions(-) Index: llvm/test/Regression/CodeGen/PowerPC/fma.ll diff -u llvm/test/Regression/CodeGen/PowerPC/fma.ll:1.1 llvm/test/Regression/CodeGen/PowerPC/fma.ll:1.2 --- llvm/test/Regression/CodeGen/PowerPC/fma.ll:1.1 Fri Apr 8 23:01:32 2005 +++ llvm/test/Regression/CodeGen/PowerPC/fma.ll Sat Apr 9 03:29:59 2005 @@ -1,6 +1,11 @@ -; RUN: llvm-as < %s | llc -march=ppc32 -enable-ppc-pattern-isel | grep 'fn\?madd\|fn\?msub' | wc -l | grep 5 +; RUN: llvm-as < %s | llc -march=ppc32 -enable-ppc-pattern-isel | grep 'fn\?madd\|fn\?msub' | wc -l | grep 7 -double %test_FMADD(double %A, double %B, double %C) { +double %test_FMADD1(double %A, double %B, double %C) { + %D = mul double %A, %B + %E = add double %D, %C + ret double %E +} +double %test_FMADD2(double %A, double %B, double %C) { %D = mul double %A, %B %E = add double %D, %C ret double %E @@ -12,19 +17,24 @@ } double %test_FNMADD1(double %A, double %B, double %C) { %D = mul double %A, %B - %E = sub double %D, %C + %E = add double %D, %C %F = sub double -0.0, %E ret double %F } double %test_FNMADD2(double %A, double %B, double %C) { %D = mul double %A, %B - %E = add double %D, %C + %E = add double %C, %D %F = sub double -0.0, %E ret double %F } -double %test_FNMADD3(double %A, double %B, double %C) { +double %test_FNMSUB1(double %A, double %B, double %C) { %D = mul double %A, %B - %E = add double %C, %D + %E = sub double %C, %D + ret double %E +} +double %test_FNMSUB2(double %A, double %B, double %C) { + %D = mul double %A, %B + %E = sub double %D, %C %F = sub double -0.0, %E ret double %F } From natebegeman at mac.com Sat Apr 9 04:30:22 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 9 Apr 2005 04:30:22 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/fnegsel.ll Message-ID: <200504090930.EAA18079@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: fnegsel.ll added (r1.1) --- Log message: Add a testcase to make sure that we don't emit two fneg instructions back to back for certain fsel instructions. --- Diffs of the changes: (+8 -0) fnegsel.ll | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/fnegsel.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/fnegsel.ll:1.1 *** /dev/null Sat Apr 9 04:30:19 2005 --- llvm/test/Regression/CodeGen/PowerPC/fnegsel.ll Sat Apr 9 04:30:09 2005 *************** *** 0 **** --- 1,8 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 -enable-ppc-pattern-isel | not grep fneg + + double %test_fneg_sel(double %A, double %B, double %C) { + %D = sub double -0.0, %A + %Cond = setgt double %D, -0.0 + %E = select bool %Cond, double %B, double %C + ret double %E + } From natebegeman at mac.com Sat Apr 9 04:33:18 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 9 Apr 2005 04:33:18 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504090933.EAA19003@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.54 -> 1.55 --- Log message: Optimize FSEL a bit for fneg arguments. This fixes the recently added test case so that we emit _test_fneg_sel: .LBB_test_fneg_sel_0: ; fsel f1, f1, f3, f2 blr instead of: _test_fneg_sel: .LBB_test_fneg_sel_0: ; fneg f0, f1 fneg f0, f0 fsel f1, f0, f3, f2 blr --- Diffs of the changes: (+12 -11) PPC32ISelPattern.cpp | 23 ++++++++++++----------- 1 files changed, 12 insertions(+), 11 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.54 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.55 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.54 Fri Apr 8 22:22:30 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Apr 9 04:33:07 2005 @@ -999,7 +999,6 @@ SetCC->getCondition() != ISD::SETEQ && SetCC->getCondition() != ISD::SETNE) { MVT::ValueType VT = SetCC->getOperand(0).getValueType(); - Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against unsigned TV = SelectExpr(N.getOperand(1)); // Use if TRUE unsigned FV = SelectExpr(N.getOperand(2)); // Use if FALSE @@ -1009,29 +1008,31 @@ default: assert(0 && "Invalid FSEL condition"); abort(); case ISD::SETULT: case ISD::SETLT: - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(FV).addReg(TV); - return Result; + std::swap(TV, FV); // fsel is natively setge, swap operands for setlt case ISD::SETUGE: case ISD::SETGE: + Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(TV).addReg(FV); return Result; case ISD::SETUGT: - case ISD::SETGT: { - Tmp2 = MakeReg(VT); - BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1); - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(FV).addReg(TV); - return Result; - } + case ISD::SETGT: + std::swap(TV, FV); // fsel is natively setge, swap operands for setlt case ISD::SETULE: case ISD::SETLE: { - Tmp2 = MakeReg(VT); - BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1); + if (SetCC->getOperand(0).getOpcode() == ISD::FNEG) { + Tmp2 = SelectExpr(SetCC->getOperand(0).getOperand(0)); + } else { + Tmp2 = MakeReg(VT); + Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against + BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1); + } BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(TV).addReg(FV); return Result; } } } else { Opc = (MVT::f64 == VT) ? PPC::FSUB : PPC::FSUBS; + Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against Tmp2 = SelectExpr(SetCC->getOperand(1)); Tmp3 = MakeReg(VT); switch(SetCC->getCondition()) { From duraid at octopus.com.au Sat Apr 9 06:53:11 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Sat, 9 Apr 2005 06:53:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64RegisterInfo.td Message-ID: <200504091153.GAA11987@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64RegisterInfo.td updated: 1.2 -> 1.3 --- Log message: ok, the "ia64 has a boatload of registers" joke stopped being funny today ;) * fix overallocation of integer (stacked) registers: we can't allocate registers for local use if they are required as output registers this fixes 'toast' in the test suite, and all sorts of larger programs like bzip2 etc. --- Diffs of the changes: (+6 -1) IA64RegisterInfo.td | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/lib/Target/IA64/IA64RegisterInfo.td diff -u llvm/lib/Target/IA64/IA64RegisterInfo.td:1.2 llvm/lib/Target/IA64/IA64RegisterInfo.td:1.3 --- llvm/lib/Target/IA64/IA64RegisterInfo.td:1.2 Wed Apr 6 01:17:54 2005 +++ llvm/lib/Target/IA64/IA64RegisterInfo.td Sat Apr 9 06:53:00 2005 @@ -254,7 +254,12 @@ { let Methods = [{ iterator allocation_order_end(MachineFunction &MF) const { - return end()-7; // 7 special registers + int numReservedRegs=7; // the 7 special registers r0,r1,r2,r12,r13 etc + // we also can't allocate registers for use as locals if they're + // already required as 'out' registers + numReservedRegs+=MF.getInfo()->outRegsUsed; + + return end()-numReservedRegs; // hide registers appropriately } }]; } From lattner at cs.uiuc.edu Sat Apr 9 10:23:10 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 10:23:10 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineFunction.h Message-ID: <200504091523.j39FNAxu031199@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineFunction.h updated: 1.50 -> 1.51 --- Log message: add routines to track the livein/out set for a function --- Diffs of the changes: (+21 -0) MachineFunction.h | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/include/llvm/CodeGen/MachineFunction.h diff -u llvm/include/llvm/CodeGen/MachineFunction.h:1.50 llvm/include/llvm/CodeGen/MachineFunction.h:1.51 --- llvm/include/llvm/CodeGen/MachineFunction.h:1.50 Thu Mar 17 12:23:22 2005 +++ llvm/include/llvm/CodeGen/MachineFunction.h Sat Apr 9 10:22:53 2005 @@ -105,6 +105,11 @@ /// for other target specific uses. bool *UsedPhysRegs; + /// LiveIns/LiveOuts - Keep track of the physical registers that are + /// livein/liveout of the function. Live in values are typically arguments in + /// registers, live out values are typically return values in registers. + std::vector LiveIns, LiveOuts; + public: MachineFunction(const Function *Fn, const TargetMachine &TM); ~MachineFunction(); @@ -167,6 +172,22 @@ /// allocation to keep the PhysRegsUsed array up-to-date. void changePhyRegUsed(unsigned Reg, bool State) { UsedPhysRegs[Reg] = State; } + + // LiveIn/LiveOut management methods. + + /// addLiveIn/Out - Add the specified register as a live in/out. Note that it + /// is an error to add the same register to the same set more than once. + void addLiveIn(unsigned Reg) { LiveIns.push_back(Reg); } + void addLiveOut(unsigned Reg) { LiveOuts.push_back(Reg); } + + // Iteration support for live in/out sets. These sets are kept in sorted + // order by their register number. + typedef std::vector::const_iterator liveinout_iterator; + liveinout_iterator livein_begin() const { return LiveIns.begin(); } + liveinout_iterator livein_end() const { return LiveIns.end(); } + liveinout_iterator liveout_begin() const { return LiveOuts.begin(); } + liveinout_iterator liveout_end() const { return LiveOuts.end(); } + /// getBlockNumbered - MachineBasicBlocks are automatically numbered when they /// are inserted into the machine function. The block number for a machine /// basic block can be found by using the MBB::getBlockNumber method, this From lattner at cs.uiuc.edu Sat Apr 9 10:23:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 10:23:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveVariables.cpp Message-ID: <200504091523.j39FNfmN031262@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveVariables.cpp updated: 1.47 -> 1.48 --- Log message: Consider the livein/out set for a function, allowing targets to not have to use ugly imp_def/imp_uses for arguments and return values. --- Diffs of the changes: (+20 -0) LiveVariables.cpp | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+) Index: llvm/lib/CodeGen/LiveVariables.cpp diff -u llvm/lib/CodeGen/LiveVariables.cpp:1.47 llvm/lib/CodeGen/LiveVariables.cpp:1.48 --- llvm/lib/CodeGen/LiveVariables.cpp:1.47 Wed Jan 19 11:11:51 2005 +++ llvm/lib/CodeGen/LiveVariables.cpp Sat Apr 9 10:23:25 2005 @@ -163,6 +163,14 @@ /// Get some space for a respectable number of registers... VirtRegInfo.resize(64); + + // Mark live-in registers as live-in. + for (MachineFunction::liveinout_iterator I = MF.livein_begin(), + E = MF.livein_end(); I != E; ++I) { + assert(MRegisterInfo::isPhysicalRegister(*I) && + "Cannot have a live-in virtual register!"); + HandlePhysRegDef(*I, 0); + } // Calculate live variable information in depth first order on the CFG of the // function. This guarantees that we will see the definition of a virtual @@ -260,6 +268,18 @@ } } + // Finally, if the last block in the function is a return, make sure to mark + // it as using all of the live-out values in the function. + if (!MBB->empty() && TII.isReturn(MBB->back().getOpcode())) { + MachineInstr *Ret = &MBB->back(); + for (MachineFunction::liveinout_iterator I = MF.liveout_begin(), + E = MF.liveout_end(); I != E; ++I) { + assert(MRegisterInfo::isPhysicalRegister(*I) && + "Cannot have a live-in virtual register!"); + HandlePhysRegUse(*I, Ret); + } + } + // Loop over PhysRegInfo, killing any registers that are available at the // end of the basic block. This also resets the PhysRegInfo map. for (unsigned i = 0, e = RegInfo->getNumRegs(); i != e; ++i) From lattner at cs.uiuc.edu Sat Apr 9 10:24:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 10:24:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp X86ISelSimple.cpp Message-ID: <200504091524.j39FOD8S031279@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.102 -> 1.103 X86ISelSimple.cpp updated: 1.311 -> 1.312 --- Log message: Use live out sets for return values instead of imp_defs, which is cleaner and faster. --- Diffs of the changes: (+41 -14) X86ISelPattern.cpp | 26 ++++++++++++++++++++------ X86ISelSimple.cpp | 29 +++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 14 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.102 llvm/lib/Target/X86/X86ISelPattern.cpp:1.103 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.102 Fri Apr 8 22:22:37 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Sat Apr 9 10:23:56 2005 @@ -160,6 +160,26 @@ if (F.isVarArg()) VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset); ReturnAddrIndex = 0; // No return address slot generated yet. + + // Finally, inform the code generator which regs we return values in. + switch (getValueType(F.getReturnType())) { + default: assert(0 && "Unknown type!"); + case MVT::isVoid: break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + MF.addLiveOut(X86::EAX); + break; + case MVT::i64: + MF.addLiveOut(X86::EAX); + MF.addLiveOut(X86::EDX); + break; + case MVT::f32: + case MVT::f64: + MF.addLiveOut(X86::ST0); + break; + } return ArgValues; } @@ -2929,9 +2949,6 @@ BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(Tmp1); BuildMI(BB, X86::MOV32rr, 1, X86::EDX).addReg(Tmp2); - // Declare that EAX & EDX are live on exit. - BuildMI(BB, X86::IMPLICIT_USE, 3).addReg(X86::EAX).addReg(X86::EDX) - .addReg(X86::ESP); break; case 2: if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) { @@ -2945,12 +2962,9 @@ default: assert(0 && "All other types should have been promoted!!"); case MVT::f64: BuildMI(BB, X86::FpSETRESULT, 1).addReg(Tmp1); - // Declare that top-of-stack is live on exit - BuildMI(BB, X86::IMPLICIT_USE, 2).addReg(X86::ST0).addReg(X86::ESP); break; case MVT::i32: BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(Tmp1); - BuildMI(BB, X86::IMPLICIT_USE, 2).addReg(X86::EAX).addReg(X86::ESP); break; } break; Index: llvm/lib/Target/X86/X86ISelSimple.cpp diff -u llvm/lib/Target/X86/X86ISelSimple.cpp:1.311 llvm/lib/Target/X86/X86ISelSimple.cpp:1.312 --- llvm/lib/Target/X86/X86ISelSimple.cpp:1.311 Wed Apr 6 15:59:35 2005 +++ llvm/lib/Target/X86/X86ISelSimple.cpp Sat Apr 9 10:23:56 2005 @@ -618,7 +618,8 @@ unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot MachineFrameInfo *MFI = F->getFrameInfo(); - for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end(); I != E; ++I) { + for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end(); + I != E; ++I) { bool ArgLive = !I->use_empty(); unsigned Reg = ArgLive ? getReg(*I) : 0; int FI; // Frame object index @@ -676,6 +677,25 @@ // llvm.va_start. if (Fn.getFunctionType()->isVarArg()) VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset); + + // Finally, inform the compiler what our live-outs will be, aka, what we will + // be returning in registers. + if (Fn.getReturnType() != Type::VoidTy) + switch (getClassB(Fn.getReturnType())) { + default: assert(0 && "Unknown type!"); + case cByte: + case cShort: + case cInt: + F->addLiveOut(X86::EAX); + break; + case cLong: + F->addLiveOut(X86::EAX); + F->addLiveOut(X86::EDX); + break; + case cFP: + F->addLiveOut(X86::ST0); + break; + } } /// EmitSpecialCodeForMain - Emit any code that needs to be executed only in @@ -1434,23 +1454,16 @@ case cShort: case cInt: promote32(X86::EAX, ValueRecord(RetVal)); - // Declare that EAX is live on exit - BuildMI(BB, X86::IMPLICIT_USE, 2).addReg(X86::EAX).addReg(X86::ESP); break; case cFP: { // Floats & Doubles: Return in ST(0) unsigned RetReg = getReg(RetVal); BuildMI(BB, X86::FpSETRESULT, 1).addReg(RetReg); - // Declare that top-of-stack is live on exit - BuildMI(BB, X86::IMPLICIT_USE, 2).addReg(X86::ST0).addReg(X86::ESP); break; } case cLong: { unsigned RetReg = getReg(RetVal); BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(RetReg); BuildMI(BB, X86::MOV32rr, 1, X86::EDX).addReg(RetReg+1); - // Declare that EAX & EDX are live on exit - BuildMI(BB, X86::IMPLICIT_USE, 3).addReg(X86::EAX).addReg(X86::EDX) - .addReg(X86::ESP); break; } default: From lattner at cs.uiuc.edu Sat Apr 9 11:18:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 11:18:07 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200504091618.j39GI7Hd003034@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.136 -> 1.137 --- Log message: Adjust live intervals to support a livein set --- Diffs of the changes: (+44 -2) LiveIntervalAnalysis.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 44 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.136 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.137 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.136 Thu Mar 10 14:59:51 2005 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Sat Apr 9 11:17:50 2005 @@ -91,6 +91,28 @@ allocatableRegs_ = mri_->getAllocatableSet(fn); r2rMap_.grow(mf_->getSSARegMap()->getLastVirtReg()); + // If this function has any live ins, insert a dummy instruction at the + // beginning of the function that we will pretend "defines" the values. This + // is to make the interval analysis simpler by providing a number. + if (fn.livein_begin() != fn.livein_end()) { + unsigned FirstLiveIn = *fn.livein_begin(); + + // Find a reg class that contains this live in. + const TargetRegisterClass *RC = 0; + for (MRegisterInfo::regclass_iterator RCI = mri_->regclass_begin(), + E = mri_->regclass_end(); RCI != E; ++RCI) + if ((*RCI)->contains(FirstLiveIn)) { + RC = *RCI; + break; + } + + MachineInstr *OldFirstMI = fn.begin()->begin(); + mri_->copyRegToReg(*fn.begin(), fn.begin()->begin(), + FirstLiveIn, FirstLiveIn, RC); + assert(OldFirstMI != fn.begin()->begin() && + "copyRetToReg didn't insert anything!"); + } + // number MachineInstrs unsigned miIndex = 0; for (MachineFunction::iterator mbb = mf_->begin(), mbbEnd = mf_->end(); @@ -103,6 +125,19 @@ miIndex += InstrSlots::NUM; } + // Note intervals due to live-in values. + if (fn.livein_begin() != fn.livein_end()) { + MachineBasicBlock *Entry = fn.begin(); + for (MachineFunction::liveinout_iterator I = fn.livein_begin(), + E = fn.livein_end(); I != E; ++I) { + handlePhysicalRegisterDef(Entry, Entry->begin(), + getOrCreateInterval(*I), 0, 0); + for (const unsigned* AS = mri_->getAliasSet(*I); *AS; ++AS) + handlePhysicalRegisterDef(Entry, Entry->begin(), + getOrCreateInterval(*AS), 0, 0); + } + } + computeIntervals(); numIntervals += getNumIntervals(); @@ -164,6 +199,11 @@ } } + // If we inserted a placeholder instruction at the entry of the block, remove + // it now. + if (fn.livein_begin() != fn.livein_end()) + fn.begin()->erase(fn.begin()->begin()); + DEBUG(dump()); return true; } @@ -557,14 +597,16 @@ DEBUG(std::cerr << "********** COMPUTING LIVE INTERVALS **********\n"); DEBUG(std::cerr << "********** Function: " << ((Value*)mf_->getFunction())->getName() << '\n'); + bool IgnoreFirstInstr = mf_->livein_begin() != mf_->livein_end(); for (MachineFunction::iterator I = mf_->begin(), E = mf_->end(); I != E; ++I) { MachineBasicBlock* mbb = I; DEBUG(std::cerr << ((Value*)mbb->getBasicBlock())->getName() << ":\n"); - for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); - mi != miEnd; ++mi) { + MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); + if (IgnoreFirstInstr) { ++mi; IgnoreFirstInstr = false; } + for (; mi != miEnd; ++mi) { const TargetInstrDescriptor& tid = tm_->getInstrInfo()->get(mi->getOpcode()); DEBUG(std::cerr << getInstructionIndex(mi) << "\t" << *mi); From lattner at cs.uiuc.edu Sat Apr 9 11:24:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 11:24:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200504091624.j39GOYiB003150@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.137 -> 1.138 --- Log message: there is no need to remove this instruction, linscan does it already as it removes noop moves. --- Diffs of the changes: (+0 -5) LiveIntervalAnalysis.cpp | 5 ----- 1 files changed, 5 deletions(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.137 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.138 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.137 Sat Apr 9 11:17:50 2005 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Sat Apr 9 11:24:20 2005 @@ -199,11 +199,6 @@ } } - // If we inserted a placeholder instruction at the entry of the block, remove - // it now. - if (fn.livein_begin() != fn.livein_end()) - fn.begin()->erase(fn.begin()->begin()); - DEBUG(dump()); return true; } From lattner at persephone.cs.uiuc.edu Sat Apr 9 11:32:59 2005 From: lattner at persephone.cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 11:32:59 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Message-ID: <20050409163259.8D28BCA7680@persephone.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelSimple.cpp updated: 1.134 -> 1.135 --- Log message: Switch this instruction selector over to using liveins and liveouts, eliminating implicit defs on entry to the function. yaay :) --- Diffs of the changes: (+26 -8) PPC32ISelSimple.cpp | 34 ++++++++++++++++++++++++++-------- 1 files changed, 26 insertions, 8 deletions Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.134 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.135 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.134 Wed Apr 6 17:42:08 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Sat Apr 9 11:32:30 2005 @@ -729,7 +729,8 @@ MachineFrameInfo *MFI = F->getFrameInfo(); - for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end(); I != E; ++I) { + for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end(); + I != E; ++I) { bool ArgLive = !I->use_empty(); unsigned Reg = ArgLive ? getReg(*I) : 0; int FI; // Frame object index @@ -739,7 +740,7 @@ if (ArgLive) { FI = MFI->CreateFixedObject(4, ArgOffset); if (GPR_remaining > 0) { - BuildMI(BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); + F->addLiveIn(GPR[GPR_idx]); BuildMI(BB, PPC::OR, 2, Reg).addReg(GPR[GPR_idx]) .addReg(GPR[GPR_idx]); } else { @@ -751,7 +752,7 @@ if (ArgLive) { FI = MFI->CreateFixedObject(4, ArgOffset); if (GPR_remaining > 0) { - BuildMI(BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); + F->addLiveIn(GPR[GPR_idx]); BuildMI(BB, PPC::OR, 2, Reg).addReg(GPR[GPR_idx]) .addReg(GPR[GPR_idx]); } else { @@ -763,7 +764,7 @@ if (ArgLive) { FI = MFI->CreateFixedObject(4, ArgOffset); if (GPR_remaining > 0) { - BuildMI(BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); + F->addLiveIn(GPR[GPR_idx]); BuildMI(BB, PPC::OR, 2, Reg).addReg(GPR[GPR_idx]) .addReg(GPR[GPR_idx]); } else { @@ -775,8 +776,8 @@ if (ArgLive) { FI = MFI->CreateFixedObject(8, ArgOffset); if (GPR_remaining > 1) { - BuildMI(BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); - BuildMI(BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx+1]); + F->addLiveIn(GPR[GPR_idx]); + F->addLiveIn(GPR[GPR_idx+1]); BuildMI(BB, PPC::OR, 2, Reg).addReg(GPR[GPR_idx]) .addReg(GPR[GPR_idx]); BuildMI(BB, PPC::OR, 2, Reg+1).addReg(GPR[GPR_idx+1]) @@ -798,7 +799,7 @@ FI = MFI->CreateFixedObject(4, ArgOffset); if (FPR_remaining > 0) { - BuildMI(BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]); + F->addLiveIn(FPR[FPR_idx]); BuildMI(BB, PPC::FMR, 1, Reg).addReg(FPR[FPR_idx]); FPR_remaining--; FPR_idx++; @@ -812,7 +813,7 @@ FI = MFI->CreateFixedObject(8, ArgOffset); if (FPR_remaining > 0) { - BuildMI(BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]); + F->addLiveIn(FPR[FPR_idx]); BuildMI(BB, PPC::FMR, 1, Reg).addReg(FPR[FPR_idx]); FPR_remaining--; FPR_idx++; @@ -843,6 +844,23 @@ // llvm.va_start. if (Fn.getFunctionType()->isVarArg()) VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); + + if (Fn.getReturnType() != Type::VoidTy) + switch (getClassB(Fn.getReturnType())) { + case cByte: + case cShort: + case cInt: + F->addLiveOut(PPC::R3); + break; + case cLong: + F->addLiveOut(PPC::R3); + F->addLiveOut(PPC::R4); + break; + case cFP32: + case cFP64: + F->addLiveOut(PPC::F1); + break; + } } From lattner at cs.uiuc.edu Sat Apr 9 14:47:37 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 14:47:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Message-ID: <200504091947.j39JlbR2004246@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelSimple.cpp updated: 1.135 -> 1.136 --- Log message: Fix a crash on 173.applu by asking for a constant bigger than 32-bits. --- Diffs of the changes: (+1 -1) PPC32ISelSimple.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.135 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.136 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.135 Sat Apr 9 11:32:30 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Sat Apr 9 14:47:21 2005 @@ -3742,7 +3742,7 @@ User::op_iterator IdxEnd = GEPI->op_end(); const TargetData &TD = TM.getTargetData(); const Type *Ty = Src->getType(); - int64_t constValue = 0; + int32_t constValue = 0; // Record the operations to emit the GEP in a vector so that we can emit them // after having analyzed the entire instruction. From lattner at cs.uiuc.edu Sat Apr 9 15:08:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 15:08:41 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/186.crafty/Makefile Message-ID: <200504092008.j39K8f3g004721@apoc.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/186.crafty: Makefile updated: 1.9 -> 1.10 --- Log message: unbreak this on x86 and other platforms. This may break alpha again... --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/External/SPEC/CINT2000/186.crafty/Makefile diff -u llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.9 llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.10 --- llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.9 Mon Apr 4 15:04:00 2005 +++ llvm-test/External/SPEC/CINT2000/186.crafty/Makefile Sat Apr 9 15:08:26 2005 @@ -3,7 +3,7 @@ STDIN_FILENAME = crafty.in STDOUT_FILENAME = crafty.out -ifeq ($(ARCH),Alpha) +ifneq ($(ARCH),Alpha) CPPFLAGS = -DSPEC_CPU2000 -DLINUX_i386 else CPPFLAGS = -DSPEC_CPU2000 -DALPHA -DLINUX From natebegeman at mac.com Sat Apr 9 15:09:23 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 9 Apr 2005 15:09:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PowerPCInstrInfo.td Message-ID: <200504092009.PAA17333@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.55 -> 1.56 PowerPCInstrInfo.td updated: 1.55 -> 1.56 --- Log message: Add rlwnm instruction for variable rotate Generate rotate left/right immediate Generate code for brcondtwoway Use new livein/liveout functionality --- Diffs of the changes: (+79 -29) PPC32ISelPattern.cpp | 104 +++++++++++++++++++++++++++++++++++++-------------- PowerPCInstrInfo.td | 4 + 2 files changed, 79 insertions(+), 29 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.55 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.56 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.55 Sat Apr 9 04:33:07 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Apr 9 15:09:12 2005 @@ -16,7 +16,7 @@ #include "PowerPC.h" #include "PowerPCInstrBuilder.h" #include "PowerPCInstrInfo.h" -#include "PPC32RegisterInfo.h" +#include "PPC32TargetMachine.h" #include "llvm/Constants.h" // FIXME: REMOVE #include "llvm/Function.h" #include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE @@ -49,7 +49,6 @@ addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass); // PowerPC has no intrinsics for these particular operations - setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); setOperationAction(ISD::MEMSET, MVT::Other, Expand); setOperationAction(ISD::MEMCPY, MVT::Other, Expand); @@ -129,6 +128,7 @@ SDOperand newroot, argt; unsigned ObjSize; bool needsLoad = false; + bool ArgLive = !I->use_empty(); MVT::ValueType ObjectVT = getValueType(I->getType()); switch (ObjectVT) { @@ -138,8 +138,9 @@ case MVT::i16: case MVT::i32: ObjSize = 4; + if (!ArgLive) break; if (GPR_remaining > 0) { - BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); + MF.addLiveIn(GPR[GPR_idx]); argt = newroot = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot()); if (ObjectVT != MVT::i32) @@ -149,10 +150,11 @@ } break; case MVT::i64: ObjSize = 8; + if (!ArgLive) break; // FIXME: can split 64b load between reg/mem if it is last arg in regs if (GPR_remaining > 1) { - BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); - BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx+1]); + MF.addLiveIn(GPR[GPR_idx]); + MF.addLiveIn(GPR[GPR_idx+1]); // Copy the extracted halves into the virtual registers SDOperand argHi = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot()); @@ -164,10 +166,12 @@ needsLoad = true; } break; - case MVT::f32: ObjSize = 4; - case MVT::f64: ObjSize = 8; + case MVT::f32: + case MVT::f64: + ObjSize = (ObjectVT == MVT::f64) ? 8 : 4; + if (!ArgLive) break; if (FPR_remaining > 0) { - BuildMI(&BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]); + MF.addLiveIn(FPR[FPR_idx]); argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT, DAG.getRoot()); --FPR_remaining; @@ -214,7 +218,7 @@ // result of va_next. std::vector MemOps; for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) { - BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); + MF.addLiveIn(GPR[GPR_idx]); SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot()); SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), Val, FIN); @@ -226,6 +230,26 @@ DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps)); } + // Finally, inform the code generator which regs we return values in. + switch (getValueType(F.getReturnType())) { + default: assert(0 && "Unknown type!"); + case MVT::isVoid: break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + MF.addLiveOut(PPC::R3); + break; + case MVT::i64: + MF.addLiveOut(PPC::R3); + MF.addLiveOut(PPC::R4); + break; + case MVT::f32: + case MVT::f64: + MF.addLiveOut(PPC::F1); + break; + } + return ArgValues; } @@ -440,7 +464,7 @@ } namespace { -Statistic<>NotLogic("ppc-codegen", "Number of inverted logical ops"); +Statistic<>Rotates("ppc-codegen", "Number of rotates emitted"); Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations"); //===--------------------------------------------------------------------===// /// ISel - PPC32 specific code to select PPC32 machine instructions for @@ -837,6 +861,7 @@ /// 3. or shr, and 7. or shr, shl /// 4. or and, shr bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) { + bool IsRotate = false; unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, Amount = 0; unsigned Op0Opc = OR.getOperand(0).getOpcode(); unsigned Op1Opc = OR.getOperand(1).getOpcode(); @@ -865,12 +890,14 @@ switch(Op1Opc) { case ISD::SHL: Amount = CN->getValue(); - InsMask <<= Amount; + InsMask <<= Amount; + if (Op0Opc == ISD::SRL) IsRotate = true; break; case ISD::SRL: Amount = CN->getValue(); InsMask >>= Amount; Amount = 32-Amount; + if (Op0Opc == ISD::SHL) IsRotate = true; break; case ISD::AND: InsMask &= (unsigned)CN->getValue(); @@ -887,6 +914,16 @@ unsigned MB, ME; if (((TgtMask ^ InsMask) == 0xFFFFFFFF) && IsRunOfOnes(InsMask, MB, ME)) { unsigned Tmp1, Tmp2; + // Check for rotlwi / rotrwi here, a special case of bitfield insert + // where both bitfield halves are sourced from the same value. + if (IsRotate && + OR.getOperand(0).getOperand(0) == OR.getOperand(1).getOperand(0)) { + ++Rotates; // Statistic + Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0)); + BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(Amount) + .addImm(0).addImm(31); + return true; + } if (Op0Opc == ISD::AND) Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0)); else @@ -954,26 +991,38 @@ void ISel::SelectBranchCC(SDOperand N) { - assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???"); MachineBasicBlock *Dest = cast(N.getOperand(2))->getBasicBlock(); - // Get the MBB we will fall through to so that we can hand it off to the - // branch selection pass as an argument to the PPC::COND_BRANCH pseudo op. - //ilist::iterator It = BB; - //MachineBasicBlock *Fallthrough = ++It; - Select(N.getOperand(0)); //chain unsigned Opc = SelectSetCR0(N.getOperand(1)); - // FIXME: Use this once we have something approximating two-way branches - // We cannot currently use this in case the ISel hands us something like - // BRcc MBBx - // BR MBBy - // since the fallthrough basic block for the conditional branch does not start - // with the unconditional branch (it is skipped over). - //BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc) - // .addMBB(Dest).addMBB(Fallthrough); - BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest); + + // Iterate to the next basic block, unless we're already at the end of the + ilist::iterator It = BB, E = BB->getParent()->end(); + if (It != E) ++It; + + // If this is a two way branch, then grab the fallthrough basic block argument + // and build a PowerPC branch pseudo-op, suitable for long branch conversion + // if necessary by the branch selection pass. Otherwise, emit a standard + // conditional branch. + if (N.getOpcode() == ISD::BRCONDTWOWAY) { + MachineBasicBlock *Fallthrough = + cast(N.getOperand(3))->getBasicBlock(); + if (Dest != It) { + BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc) + .addMBB(Dest).addMBB(Fallthrough); + if (Fallthrough != It) + BuildMI(BB, PPC::B, 1).addMBB(Fallthrough); + } else { + if (Fallthrough != It) { + Opc = PPC32InstrInfo::invertPPCBranchOpcode(Opc); + BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc) + .addMBB(Fallthrough).addMBB(Dest); + } + } + } else { + BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest); + } return; } @@ -1670,7 +1719,6 @@ if (N.getOperand(0).getOpcode() == ISD::XOR && N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(0).getOperand(1))->isAllOnesValue()) { - ++NotLogic; Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); BuildMI(BB, PPC::EQV, 2, Result).addReg(Tmp1).addReg(Tmp2); @@ -1679,7 +1727,6 @@ // Check for NOT, NOR, and NAND: xor (copy, or, and), -1 if (N.getOperand(1).getOpcode() == ISD::Constant && cast(N.getOperand(1))->isAllOnesValue()) { - ++NotLogic; switch(N.getOperand(0).getOpcode()) { case ISD::OR: Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); @@ -2145,6 +2192,7 @@ return; } case ISD::BRCOND: + case ISD::BRCONDTWOWAY: SelectBranchCC(N); return; case ISD::CopyToReg: Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.55 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.56 --- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.55 Tue Apr 5 19:25:27 2005 +++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Sat Apr 9 15:09:12 2005 @@ -458,7 +458,9 @@ def RLWINM : MForm_2<21, 0, 0, 0, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME), "rlwinm $rA, $rS, $SH, $MB, $ME">; - +def RLWNM : MForm_2<23, 0, 0, 0, + (ops GPRC:$rA, GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME), + "rlwnm $rA, $rS, $rB, $MB, $ME">; // MD-Form instructions. 64 bit rotate instructions. // From lattner at cs.uiuc.edu Sat Apr 9 16:23:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 16:23:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504092123.j39LNfUA006406@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.56 -> 1.57 --- Log message: do not set the root to null if an argument is dead --- Diffs of the changes: (+2 -1) PPC32ISelPattern.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.56 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.57 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.56 Sat Apr 9 15:09:12 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Apr 9 16:23:24 2005 @@ -203,8 +203,9 @@ GPR_idx += delta; } ArgOffset += ObjSize; + if (newroot.Val) + DAG.setRoot(newroot.getValue(1)); - DAG.setRoot(newroot.getValue(1)); ArgValues.push_back(argt); } From lattner at cs.uiuc.edu Sat Apr 9 16:44:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 16:44:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504092144.j39LiBAm006796@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.66 -> 1.67 --- Log message: add a little peephole optimization. This allows us to codegen: int a(short i) { return i & 1; } as _a: andi. r3, r3, 1 blr instead of: _a: rlwinm r2, r3, 0, 16, 31 andi. r3, r2, 1 blr on ppc. It should also help the other risc targets. --- Diffs of the changes: (+11 -0) SelectionDAG.cpp | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.66 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.67 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.66 Sat Apr 9 00:15:53 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Apr 9 16:43:54 2005 @@ -766,6 +766,17 @@ if (!C2) return N2; // X and 0 -> 0 if (N2C->isAllOnesValue()) return N1; // X and -1 -> X + + // and (zero_extend_inreg x:16:32), 1 -> and x, 1 + if (N1.getOpcode() == ISD::ZERO_EXTEND_INREG || + N1.getOpcode() == ISD::SIGN_EXTEND_INREG) { + // If we are masking out the part of our input that was extended, just + // mask the input to the extension directly. + unsigned ExtendBits = + MVT::getSizeInBits(cast(N1)->getExtraValueType()); + if ((C2 & (~0ULL << ExtendBits)) == 0) + return getNode(ISD::AND, VT, N1.getOperand(0), N2); + } break; case ISD::OR: if (!C2)return N1; // X or 0 -> X From lattner at cs.uiuc.edu Sat Apr 9 17:03:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 17:03:23 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Generic/2005-05-09-GlobalInPHI.ll Message-ID: <200504092203.j39M3Nhh006913@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Generic: 2005-05-09-GlobalInPHI.ll added (r1.1) --- Log message: new testcase that used to crash the ppc fe. It could effect any simpleisel that is not careful, so I'm checking it into the generic tests. --- Diffs of the changes: (+21 -0) 2005-05-09-GlobalInPHI.ll | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/test/Regression/CodeGen/Generic/2005-05-09-GlobalInPHI.ll diff -c /dev/null llvm/test/Regression/CodeGen/Generic/2005-05-09-GlobalInPHI.ll:1.1 *** /dev/null Sat Apr 9 17:03:20 2005 --- llvm/test/Regression/CodeGen/Generic/2005-05-09-GlobalInPHI.ll Sat Apr 9 17:03:10 2005 *************** *** 0 **** --- 1,21 ---- + ; RUN: llvm-as < %s | llc + %struct.TypHeader = type { uint, %struct.TypHeader**, [3 x sbyte], ubyte } + %.str_67 = external global [4 x sbyte] ; <[4 x sbyte]*> [#uses=1] + %.str_87 = external global [17 x sbyte] ; <[17 x sbyte]*> [#uses=1] + + implementation ; Functions: + + void %PrBinop() { + entry: + br bool false, label %cond_true, label %else.0 + + cond_true: ; preds = %entry + br label %else.0 + + else.0: + %tmp.167.1 = phi int [ cast ([17 x sbyte]* %.str_87 to int), %entry ], [ 0, %cond_true ] + call void %Pr( sbyte* getelementptr ([4 x sbyte]* %.str_67, int 0, int 0), int 0, int 0 ) + ret void + } + + declare void %Pr(sbyte*, int, int) From lattner at cs.uiuc.edu Sat Apr 9 17:05:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 17:05:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Message-ID: <200504092205.j39M5U2f006925@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelSimple.cpp updated: 1.136 -> 1.137 --- Log message: Fix CodeGen/Generic/2005-05-09-GlobalInPHI.ll, which was reduced from 254.gap. This caused the "use before a def" assertion on some programs. With this patch, 254.gap now passes with the PPC backend. --- Diffs of the changes: (+16 -0) PPC32ISelSimple.cpp | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.136 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.137 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.136 Sat Apr 9 14:47:21 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Sat Apr 9 17:05:17 2005 @@ -871,6 +871,16 @@ void PPC32ISel::SelectPHINodes() { const TargetInstrInfo &TII = *TM.getInstrInfo(); const Function &LF = *F->getFunction(); // The LLVM function... + + MachineBasicBlock::iterator MFLRIt = F->begin()->begin(); + if (GlobalBaseInitialized) { + // If we emitted a MFLR for the global base reg, get an iterator to an + // instruction after it. + while (MFLRIt->getOpcode() != PPC::MFLR) + ++MFLRIt; + ++MFLRIt; // step one MI past it. + } + for (Function::const_iterator I = LF.begin(), E = LF.end(); I != E; ++I) { const BasicBlock *BB = I; MachineBasicBlock &MBB = *MBBMap[I]; @@ -938,6 +948,12 @@ while (PI != PredMBB->end() && PI->getOpcode() == PPC::PHI) ++PI; + // If this is the entry block, and if the entry block contains a + // MFLR instruction, emit this operation after it. This is needed + // because global addresses use it. + if (PredMBB == F->begin()) + PI = MFLRIt; + ValReg = getReg(Val, PredMBB, PI); } From lattner at persephone.cs.uiuc.edu Sat Apr 9 17:31:05 2005 From: lattner at persephone.cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 17:31:05 -0500 (CDT) Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/186.crafty/Makefile Message-ID: <20050409223105.8E5B4CA92CF@persephone.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/186.crafty: Makefile updated: 1.10 -> 1.11 --- Log message: Make crafty work on ALL THREE platforms. --- Diffs of the changes: (+10 -6) Makefile | 16 ++++++++++------ 1 files changed, 10 insertions, 6 deletions Index: llvm-test/External/SPEC/CINT2000/186.crafty/Makefile diff -u llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.10 llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.11 --- llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.10 Sat Apr 9 15:08:26 2005 +++ llvm-test/External/SPEC/CINT2000/186.crafty/Makefile Sat Apr 9 17:30:36 2005 @@ -3,12 +3,6 @@ STDIN_FILENAME = crafty.in STDOUT_FILENAME = crafty.out -ifneq ($(ARCH),Alpha) -CPPFLAGS = -DSPEC_CPU2000 -DLINUX_i386 -else -CPPFLAGS = -DSPEC_CPU2000 -DALPHA -DLINUX -endif - Source = $(addprefix $(SPEC_BENCH_DIR)/src/, \ attacks.c draw.c enprise.c init.c iterate.c make.c nexte.c output.c \ preeval.c resign.c searchr.c swap.c utility.c boolean.c drawn.c \ @@ -18,3 +12,13 @@ valid.c) include ../../Makefile.spec2000 + +ifeq ($(ARCH),Alpha) + CPPFLAGS += -DALPHA -DLINUX +endif +ifeq ($(ARCH),X86) + CPPFLAGS += -DLINUX_i386 +endif +ifeq ($(ARCH),PowerPC)) + CPPFLAGS += -DLINUX_PPC32 +endif From natebegeman at mac.com Sat Apr 9 18:35:16 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 9 Apr 2005 18:35:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504092335.SAA18263@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.57 -> 1.58 --- Log message: fix ISD::BRCONDTWOWAY codegen to not deference the end() iterator --- Diffs of the changes: (+1 -1) PPC32ISelPattern.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.57 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.58 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.57 Sat Apr 9 16:23:24 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Apr 9 18:35:05 2005 @@ -1000,7 +1000,7 @@ // Iterate to the next basic block, unless we're already at the end of the ilist::iterator It = BB, E = BB->getParent()->end(); - if (It != E) ++It; + if (++It == E) It = BB; // If this is a two way branch, then grab the fallthrough basic block argument // and build a PowerPC branch pseudo-op, suitable for long branch conversion From brukman at cs.uiuc.edu Sat Apr 9 19:12:56 2005 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sat, 9 Apr 2005 19:12:56 -0500 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/CINT2000/186.crafty/Makefile Message-ID: <200504100012.TAA18504@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC/CINT2000/186.crafty: Makefile updated: 1.11 -> 1.12 --- Log message: Remove extra `)' --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/External/SPEC/CINT2000/186.crafty/Makefile diff -u llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.11 llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.12 --- llvm-test/External/SPEC/CINT2000/186.crafty/Makefile:1.11 Sat Apr 9 17:30:36 2005 +++ llvm-test/External/SPEC/CINT2000/186.crafty/Makefile Sat Apr 9 19:12:45 2005 @@ -19,6 +19,6 @@ ifeq ($(ARCH),X86) CPPFLAGS += -DLINUX_i386 endif -ifeq ($(ARCH),PowerPC)) +ifeq ($(ARCH),PowerPC) CPPFLAGS += -DLINUX_PPC32 endif From lattner at cs.uiuc.edu Sat Apr 9 20:03:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 20:03:48 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Message-ID: <200504100103.j3A13mqs008230@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelSimple.cpp updated: 1.137 -> 1.138 --- Log message: rename getPPCOpcodeForSetCCNumber -> getPPCOpcodeForSetCCOpode to be more correct. Remove the EmitComparison retvalue, as it is always the first arg. Fix a place where we incorrectly passed in the setcc opcode instead of the setcc number, causing us to miscompile crafty. Crafty now works! --- Diffs of the changes: (+21 -21) PPC32ISelSimple.cpp | 42 +++++++++++++++++++++--------------------- 1 files changed, 21 insertions(+), 21 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.137 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.138 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.137 Sat Apr 9 17:05:17 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Sat Apr 9 20:03:31 2005 @@ -292,9 +292,9 @@ // Comparison operators... void visitSetCondInst(SetCondInst &I); - unsigned EmitComparison(unsigned OpNum, Value *Op0, Value *Op1, - MachineBasicBlock *MBB, - MachineBasicBlock::iterator MBBI); + void EmitComparison(unsigned OpNum, Value *Op0, Value *Op1, + MachineBasicBlock *MBB, + MachineBasicBlock::iterator MBBI); void visitSelectInst(SelectInst &SI); @@ -1049,7 +1049,7 @@ } } -static unsigned getPPCOpcodeForSetCCNumber(unsigned Opcode) { +static unsigned getPPCOpcodeForSetCCOpcode(unsigned Opcode) { switch (Opcode) { default: assert(0 && "Unknown setcc instruction!"); case Instruction::SetEQ: return PPC::BEQ; @@ -1101,12 +1101,12 @@ return Reg; } -/// EmitComparison - emits a comparison of the two operands, returning the -/// extended setcc code to use. The result is in CR0. +/// EmitComparison - emits a comparison of the two operands. The result is in +/// CR0. /// -unsigned PPC32ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1, - MachineBasicBlock *MBB, - MachineBasicBlock::iterator IP) { +void PPC32ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1, + MachineBasicBlock *MBB, + MachineBasicBlock::iterator IP) { // The arguments are already supposed to be of the same type. const Type *CompTy = Op0->getType(); unsigned Class = getClassB(CompTy); @@ -1134,7 +1134,7 @@ unsigned Op1r = getReg(Op1, MBB, IP); BuildMI(*MBB, IP, Opcode, 2, PPC::CR0).addReg(Op0r).addReg(Op1r); } - return OpNum; + return; } else { assert(Class == cLong && "Unknown integer class!"); unsigned LowCst = CI->getRawValue(); @@ -1155,7 +1155,7 @@ BuildMI(*MBB, IP, PPC::XORIS, 2, HiTmp).addReg(HiLow) .addImm(HiCst >> 16); BuildMI(*MBB, IP, PPC::ORo, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp); - return OpNum; + return; } else { unsigned ConstReg = makeAnotherReg(CompTy); copyConstantToRegister(MBB, IP, CI, ConstReg); @@ -1168,7 +1168,7 @@ BuildMI(*MBB, IP, PPC::CRAND, 3).addImm(2).addImm(2).addImm(CR1field); BuildMI(*MBB, IP, PPC::CROR, 3).addImm(CR0field).addImm(CR0field) .addImm(2); - return OpNum; + return; } } } @@ -1207,10 +1207,10 @@ BuildMI(*MBB, IP, PPC::CRAND, 3).addImm(2).addImm(2).addImm(CR1field); BuildMI(*MBB, IP, PPC::CROR, 3).addImm(CR0field).addImm(CR0field) .addImm(2); - return OpNum; + return; } } - return OpNum; + return; } /// visitSetCondInst - emit code to calculate the condition via @@ -1306,7 +1306,7 @@ return; } } - unsigned PPCOpcode = getPPCOpcodeForSetCCNumber(Opcode); + unsigned PPCOpcode = getPPCOpcodeForSetCCOpcode(Opcode); // Create an iterator with which to insert the MBB for copying the false value // and the MBB to hold the PHI instruction for this SetCC. @@ -1320,7 +1320,7 @@ // cmpTY cr0, r1, r2 // %TrueValue = li 1 // bCC sinkMBB - EmitComparison(Opcode, Op0, Op1, BB, BB->end()); + EmitComparison(OpNum, Op0, Op1, BB, BB->end()); unsigned TrueValue = makeAnotherReg(I.getType()); BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1); MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); @@ -1446,12 +1446,12 @@ return; } } - OpNum = EmitComparison(OpNum, SCI->getOperand(0),SCI->getOperand(1),MBB,IP); - Opcode = getPPCOpcodeForSetCCNumber(SCI->getOpcode()); + EmitComparison(OpNum, SCI->getOperand(0),SCI->getOperand(1),MBB,IP); + Opcode = getPPCOpcodeForSetCCOpcode(SCI->getOpcode()); } else { unsigned CondReg = getReg(Cond, MBB, IP); BuildMI(*MBB, IP, PPC::CMPWI, 2, PPC::CR0).addReg(CondReg).addSImm(0); - Opcode = getPPCOpcodeForSetCCNumber(Instruction::SetNE); + Opcode = getPPCOpcodeForSetCCOpcode(Instruction::SetNE); } MachineBasicBlock *thisMBB = BB; @@ -1633,9 +1633,9 @@ } unsigned OpNum = getSetCCNumber(SCI->getOpcode()); - unsigned Opcode = getPPCOpcodeForSetCCNumber(SCI->getOpcode()); + unsigned Opcode = getPPCOpcodeForSetCCOpcode(SCI->getOpcode()); MachineBasicBlock::iterator MII = BB->end(); - OpNum = EmitComparison(OpNum, SCI->getOperand(0), SCI->getOperand(1), BB,MII); + EmitComparison(OpNum, SCI->getOperand(0), SCI->getOperand(1), BB,MII); if (BI.getSuccessor(0) != NextBB) { BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opcode) From lattner at cs.uiuc.edu Sat Apr 9 20:13:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 20:13:31 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp Message-ID: <200504100113.j3A1DVuO008346@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.76 -> 1.77 SelectionDAG.cpp updated: 1.67 -> 1.68 --- Log message: Fix a thinko. If the operand is promoted, pass the promoted value into the new zero extend, not the original operand. This fixes cast bool -> long on ppc. Add an unrelated fixme --- Diffs of the changes: (+5 -1) LegalizeDAG.cpp | 2 +- SelectionDAG.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.76 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.77 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.76 Fri Apr 8 22:30:19 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Apr 9 20:13:15 2005 @@ -1937,7 +1937,7 @@ // The low part is just a zero extension of the input (which degenerates to // a copy). - Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, LegalizeOp(Node->getOperand(0))); + Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, In); // The high part is just a zero. Hi = DAG.getConstant(0, NVT); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.67 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.68 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.67 Sat Apr 9 16:43:54 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Apr 9 20:13:15 2005 @@ -767,6 +767,10 @@ if (N2C->isAllOnesValue()) return N1; // X and -1 -> X + // FIXME: Should add a corresponding version of this for + // ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which + // we don't have yet. + // and (zero_extend_inreg x:16:32), 1 -> and x, 1 if (N1.getOpcode() == ISD::ZERO_EXTEND_INREG || N1.getOpcode() == ISD::SIGN_EXTEND_INREG) { From natebegeman at mac.com Sat Apr 9 20:14:24 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 9 Apr 2005 20:14:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504100114.UAA18711@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.58 -> 1.59 --- Log message: Don't hand ISD::CALL nodes off to SelectExprFP. This fixes siod. --- Diffs of the changes: (+2 -1) PPC32ISelPattern.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.58 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.59 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.58 Sat Apr 9 18:35:05 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Apr 9 20:14:13 2005 @@ -1388,7 +1388,8 @@ DestType = N.getValue(0).getValueType(); if (DestType == MVT::f64 || DestType == MVT::f32) - if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode && ISD::UNDEF != opcode) + if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode && + ISD::UNDEF != opcode && ISD::CALL != opcode) return SelectExprFP(N, Result); switch (opcode) { From natebegeman at mac.com Sat Apr 9 20:48:40 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 9 Apr 2005 20:48:40 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PowerPCAsmPrinter.cpp Message-ID: <200504100148.UAA18887@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.59 -> 1.60 PowerPCAsmPrinter.cpp updated: 1.74 -> 1.75 --- Log message: Make sure that BRCOND branches can be converted into long branches too. --- Diffs of the changes: (+4 -2) PPC32ISelPattern.cpp | 4 +++- PowerPCAsmPrinter.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.59 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.60 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.59 Sat Apr 9 20:14:13 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Apr 9 20:48:29 2005 @@ -1022,7 +1022,9 @@ } } } else { - BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest); + BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc) + .addMBB(Dest).addMBB(It); + //BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest); } return; } Index: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.74 llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.75 --- llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.74 Tue Apr 5 13:19:50 2005 +++ llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Sat Apr 9 20:48:29 2005 @@ -107,7 +107,7 @@ // Branches can take an immediate operand. This is used by the branch // selection pass to print $+8, an eight byte displacement from the PC. if (MI->getOperand(OpNo).isImmediate()) { - O << "$+" << MI->getOperand(OpNo).getImmedValue() << '\n'; + O << "$+" << MI->getOperand(OpNo).getImmedValue(); } else { printOp(MI->getOperand(OpNo), TM.getInstrInfo()->isCall(MI->getOpcode())); From lattner at cs.uiuc.edu Sat Apr 9 22:06:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 22:06:43 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c Message-ID: <200504100306.j3A36hnx009600@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2005-05-09-ComplexOps.c added (r1.1) --- Log message: new testcase for previously unsupported unary complex operators --- Diffs of the changes: (+6 -0) 2005-05-09-ComplexOps.c | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c diff -c /dev/null llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c:1.1 *** /dev/null Sat Apr 9 22:06:37 2005 --- llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c Sat Apr 9 22:06:27 2005 *************** *** 0 **** --- 1,6 ---- + // %llvmgcc %s -S -o - + + #include + #define I 1.0iF + + double __complex test(double X) { return -(X*I); } From lattner at cs.uiuc.edu Sat Apr 9 22:07:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 22:07:02 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200504100307.j3A372R7009612@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.93 -> 1.94 --- Log message: Implement - and ~ for complex numbers, fixing CFrontend/2005-05-09-ComplexOps.c --- Diffs of the changes: (+50 -0) llvm-expand.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 50 insertions(+) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.93 llvm-gcc/gcc/llvm-expand.c:1.94 --- llvm-gcc/gcc/llvm-expand.c:1.93 Fri Apr 8 23:42:55 2005 +++ llvm-gcc/gcc/llvm-expand.c Sat Apr 9 22:06:48 2005 @@ -5964,6 +5964,46 @@ InitializeComplex(Fn, DestLoc, ResultR, ResultI, 0); } +/* llvm_expand_complex_unary_expr - Expand one of the supported unary + * expressions on complex numbers (including both complex floating point and + * complex integer). Supported operations are ~ and -. + */ +static void llvm_expand_complex_unary_expr(llvm_function *Fn, tree exp, + llvm_value *DestLoc) { + llvm_type *DestTy = llvm_type_get_from_tree(TREE_TYPE(exp)); + llvm_value *Op0 = D2V(make_temporary_alloca(Fn, DestTy)); + llvm_value *Op0r, *Op0i; /* real and imaginary components. */ + llvm_value *ResultR, *ResultI; + llvm_value *Zero; + /* Expand the operand, loading real/imag parts... */ + + llvm_expand_expr(Fn, TREE_OPERAND(exp, 0), Op0); + Op0r = llvm_load_complex_part(Fn, Op0, 0, 0); + Op0i = llvm_load_complex_part(Fn, Op0, 1, 0); + + if (llvm_type_is_fp(Op0r->Ty)) { + Zero = llvm_constant_new(Op0i->Ty, "-0.0"); + } else { + Zero = llvm_constant_get_null(Op0i->Ty); + } + switch (TREE_CODE(exp)) { + case NEGATE_EXPR: /* -(a+ib) = -a + i*-b */ + ResultR = append_inst(Fn, create_binary_inst("tmp", O_Sub, Zero, Op0r)); + ResultI = append_inst(Fn, create_binary_inst("tmp", O_Sub, Zero, Op0i)); + break; + case CONJ_EXPR: /* ~(a+ib) = a + i*-b */ + ResultR = Op0r; + ResultI = append_inst(Fn, create_binary_inst("tmp", O_Sub, Zero, Op0i)); + break; + default: + debug_tree(exp); + assert(0 && "Unknown complex expression!"); + } + + if (DestLoc) + InitializeComplex(Fn, DestLoc, ResultR, ResultI, 0); +} + /* isSimpleEnoughToEvaluateUnconditionally - Return true if this expression is * simple enough to evaluate unconditionally in a case where it would normally * be only conditionally executed. @@ -6349,7 +6389,17 @@ TREE_OPERAND(exp, 0) = lang_hooks.unsave_expr_now(TREE_OPERAND(exp, 0)); break; + case CONJ_EXPR: /* ~A = Ar + i*(-Ai)*/ + assert(llvm_type_is_composite(DestTy) && "conj of noncomplex?"); + llvm_expand_complex_unary_expr(Fn, exp, DestLoc); + break; + case NEGATE_EXPR: /* -A === 0-A */ + if (llvm_type_is_composite(DestTy)) { + llvm_expand_complex_unary_expr(Fn, exp, DestLoc); + break; + } + op1 = llvm_expand_expr(Fn, TREE_OPERAND(exp, 0), 0); if (op1->Ty->ID == PointerTyID) op1 = cast_if_type_not_equal(Fn, op1, IntPtrTy); From lattner at cs.uiuc.edu Sat Apr 9 22:07:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 22:07:38 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c Message-ID: <200504100307.j3A37cMm009640@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2005-05-09-ComplexOps.c updated: 1.1 -> 1.2 --- Log message: oops add ~ --- Diffs of the changes: (+1 -1) 2005-05-09-ComplexOps.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c diff -u llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c:1.1 llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c:1.2 --- llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c:1.1 Sat Apr 9 22:06:27 2005 +++ llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c Sat Apr 9 22:07:25 2005 @@ -3,4 +3,4 @@ #include #define I 1.0iF -double __complex test(double X) { return -(X*I); } +double __complex test(double X) { return ~-(X*I); } From lattner at cs.uiuc.edu Sat Apr 9 22:18:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 22:18:32 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c Message-ID: <200504100318.j3A3IWOi009869@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2005-05-09-ComplexOps.c updated: 1.2 -> 1.3 --- Log message: make this harder --- Diffs of the changes: (+3 -0) 2005-05-09-ComplexOps.c | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c diff -u llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c:1.2 llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c:1.3 --- llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c:1.2 Sat Apr 9 22:07:25 2005 +++ llvm/test/Regression/CFrontend/2005-05-09-ComplexOps.c Sat Apr 9 22:18:18 2005 @@ -4,3 +4,6 @@ #define I 1.0iF double __complex test(double X) { return ~-(X*I); } + +_Bool EQ(double __complex A, double __complex B) { return A == B; } +_Bool NE(double __complex A, double __complex B) { return A != B; } From lattner at cs.uiuc.edu Sat Apr 9 22:18:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 22:18:50 -0500 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200504100318.j3A3IocN009881@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.94 -> 1.95 --- Log message: add support for ==/!= complex --- Diffs of the changes: (+20 -8) llvm-expand.c | 28 ++++++++++++++++++++-------- 1 files changed, 20 insertions(+), 8 deletions(-) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.94 llvm-gcc/gcc/llvm-expand.c:1.95 --- llvm-gcc/gcc/llvm-expand.c:1.94 Sat Apr 9 22:06:48 2005 +++ llvm-gcc/gcc/llvm-expand.c Sat Apr 9 22:18:37 2005 @@ -5890,11 +5890,11 @@ * expressions on complex numbers (including both complex floating point and * complex integer). Supported operations are +, -, *, and /. */ -static void llvm_expand_complex_binary_expr(llvm_function *Fn, tree exp, - llvm_value *DestLoc) { - llvm_type *DestTy = llvm_type_get_from_tree(TREE_TYPE(exp)); - llvm_value *Op0 = D2V(make_temporary_alloca(Fn, DestTy)); - llvm_value *Op1 = D2V(make_temporary_alloca(Fn, DestTy)); +static llvm_value *llvm_expand_complex_binary_expr(llvm_function *Fn, tree exp, + llvm_value *DestLoc) { + llvm_type *OpTy = llvm_type_get_from_tree(TREE_TYPE(TREE_OPERAND(exp, 0))); + llvm_value *Op0 = D2V(make_temporary_alloca(Fn, OpTy)); + llvm_value *Op1 = D2V(make_temporary_alloca(Fn, OpTy)); llvm_value *Op0r, *Op0i; /* real and imaginary components. */ llvm_value *Op1r, *Op1i; llvm_value *ResultR, *ResultI; @@ -5920,6 +5920,16 @@ ResultR = append_inst(Fn, create_binary_inst("tmp", O_Sub, Op0r, Op1r)); ResultI = append_inst(Fn, create_binary_inst("tmp", O_Sub, Op0i, Op1i)); break; + case EQ_EXPR: /* (a+ib) == (c+id) = (a == c) & (b == d) */ + ResultR = append_inst(Fn, create_binary_inst("tmp", O_SetEQ, Op0r, Op1r)); + ResultI = append_inst(Fn, create_binary_inst("tmp", O_SetEQ, Op0i, Op1i)); + return append_inst(Fn, create_binary_inst("tmp", O_And, ResultR, ResultI)); + + case NE_EXPR: /* (a+ib) != (c+id) = (a != c) | (b != d) */ + ResultR = append_inst(Fn, create_binary_inst("tmp", O_SetNE, Op0r, Op1r)); + ResultI = append_inst(Fn, create_binary_inst("tmp", O_SetNE, Op0i, Op1i)); + return append_inst(Fn, create_binary_inst("tmp", O_Or, ResultR, ResultI)); + case MULT_EXPR: { /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */ llvm_value *Tmp1 = /* a*c */ append_inst(Fn, create_binary_inst("tmp", O_Mul, Op0r, Op1r)); @@ -5962,6 +5972,7 @@ if (DestLoc) InitializeComplex(Fn, DestLoc, ResultR, ResultI, 0); + return 0; } /* llvm_expand_complex_unary_expr - Expand one of the supported unary @@ -6391,9 +6402,6 @@ case CONJ_EXPR: /* ~A = Ar + i*(-Ai)*/ assert(llvm_type_is_composite(DestTy) && "conj of noncomplex?"); - llvm_expand_complex_unary_expr(Fn, exp, DestLoc); - break; - case NEGATE_EXPR: /* -A === 0-A */ if (llvm_type_is_composite(DestTy)) { llvm_expand_complex_unary_expr(Fn, exp, DestLoc); @@ -6453,6 +6461,10 @@ llvm_expand_complex_binary_expr(Fn, exp, DestLoc); return 0; } + if ((TREE_CODE(exp) == NE_EXPR || TREE_CODE(exp) == EQ_EXPR) && + TREE_CODE(TREE_TYPE(TREE_OPERAND(exp, 0))) == COMPLEX_TYPE) { + return llvm_expand_complex_binary_expr(Fn, exp, DestLoc); + } op0 = llvm_expand_expr(Fn, TREE_OPERAND(exp, 0), 0); op1 = llvm_expand_expr(Fn, TREE_OPERAND(exp, 1), 0); From natebegeman at mac.com Sat Apr 9 22:59:53 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 9 Apr 2005 22:59:53 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Message-ID: <200504100359.WAA19378@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32RegisterInfo.cpp updated: 1.8 -> 1.9 --- Log message: Remove unnecessary Implicit Defs. Since r0 is not in allocation, we do not have to inform the register allocator it might be stepped on. --- Diffs of the changes: (+0 -4) PPC32RegisterInfo.cpp | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.8 llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.9 --- llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp:1.8 Mon Apr 4 16:48:13 2005 +++ llvm/lib/Target/PowerPC/PPC32RegisterInfo.cpp Sat Apr 9 22:59:42 2005 @@ -84,10 +84,8 @@ unsigned OC = Opcode[getIdx(getClass(SrcReg))]; if (SrcReg == PPC::LR) { BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11).addReg(PPC::LR); - BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx); } else { - BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(SrcReg),FrameIdx); } } @@ -101,11 +99,9 @@ }; unsigned OC = Opcode[getIdx(getClass(DestReg))]; if (DestReg == PPC::LR) { - BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx); BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11); } else { - BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); addFrameReference(BuildMI(MBB, MI, OC, 2, DestReg), FrameIdx); } } From lattner at cs.uiuc.edu Sat Apr 9 23:05:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 23:05:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504100405.j3A455iV010695@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.68 -> 1.69 --- Log message: add a simple xform --- Diffs of the changes: (+6 -0) SelectionDAG.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.68 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.69 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.68 Sat Apr 9 20:13:15 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Apr 9 23:04:49 2005 @@ -892,6 +892,12 @@ return getNode(ISD::SUB, VT, N1, N2.getOperand(0)); if (N1.getOpcode() == ISD::FNEG) // ((-A)+B) -> B-A return getNode(ISD::SUB, VT, N2, N1.getOperand(0)); + if (N1.getOpcode() == ISD::SUB && isa(N1.getOperand(0)) && + cast(N1.getOperand(0))->getValue() == 0) + return getNode(ISD::SUB, VT, N2, N1.getOperand(1)); // (0-A)+B -> B-A + if (N2.getOpcode() == ISD::SUB && isa(N2.getOperand(0)) && + cast(N2.getOperand(0))->getValue() == 0) + return getNode(ISD::SUB, VT, N1, N2.getOperand(1)); // A+(0-B) -> A-B break; case ISD::SUB: if (N1.getOpcode() == ISD::ADD) { From lattner at cs.uiuc.edu Sat Apr 9 23:33:24 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 23:33:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504100433.j3A4XO5J012666@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.69 -> 1.70 --- Log message: Fold zext_inreg(zextload), likewise for sext's --- Diffs of the changes: (+6 -0) SelectionDAG.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.69 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.70 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.69 Sat Apr 9 23:04:49 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Apr 9 23:33:08 2005 @@ -1101,6 +1101,12 @@ return N1; } + // If we are (zero|sign) extending a [zs]extload, return just the load. + if ((N1.getOpcode() == ISD::ZEXTLOAD && Opcode == ISD::ZERO_EXTEND_INREG) || + (N1.getOpcode() == ISD::SEXTLOAD && Opcode == ISD::SIGN_EXTEND_INREG)) + if (cast(N1)->getExtraValueType() <= EVT) + return N1; + // If we are extending the result of a setcc, and we already know the // contents of the top bits, eliminate the extension. if (N1.getOpcode() == ISD::SETCC) From lattner at cs.uiuc.edu Sat Apr 9 23:34:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 9 Apr 2005 23:34:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200504100434.j3A4Y0ic012678@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.77 -> 1.78 --- Log message: Until we have a dag combiner, promote using zextload's instead of extloads. This gives the optimizer a bit of information about the top-part of the value. --- Diffs of the changes: (+2 -1) LegalizeDAG.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.77 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.78 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.77 Sat Apr 9 20:13:15 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Apr 9 23:33:47 2005 @@ -1355,7 +1355,8 @@ case ISD::LOAD: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. - Result = DAG.getNode(ISD::EXTLOAD, NVT, Tmp1, Tmp2, VT); + // FIXME: When the DAG combiner exists, change this to use EXTLOAD! + Result = DAG.getNode(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, VT); // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); From natebegeman at mac.com Sun Apr 10 00:53:25 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sun, 10 Apr 2005 00:53:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504100553.AAA19928@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.60 -> 1.61 --- Log message: Fix 64 bit argument loading that straddles the args in regs / args on stack boundary. --- Diffs of the changes: (+15 -7) PPC32ISelPattern.cpp | 22 +++++++++++++++------- 1 files changed, 15 insertions(+), 7 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.60 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.61 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.60 Sat Apr 9 20:48:29 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sun Apr 10 00:53:14 2005 @@ -151,14 +151,22 @@ break; case MVT::i64: ObjSize = 8; if (!ArgLive) break; - // FIXME: can split 64b load between reg/mem if it is last arg in regs - if (GPR_remaining > 1) { + if (GPR_remaining > 0) { + SDOperand argHi, argLo; MF.addLiveIn(GPR[GPR_idx]); - MF.addLiveIn(GPR[GPR_idx+1]); - // Copy the extracted halves into the virtual registers - SDOperand argHi = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, - DAG.getRoot()); - SDOperand argLo = DAG.getCopyFromReg(GPR[GPR_idx+1], MVT::i32, argHi); + argHi = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot()); + // If we have two or more remaining argument registers, then both halves + // of the i64 can be sourced from there. Otherwise, the lower half will + // have to come off the stack. This can happen when an i64 is preceded + // by 28 bytes of arguments. + if (GPR_remaining > 1) { + MF.addLiveIn(GPR[GPR_idx+1]); + argLo = DAG.getCopyFromReg(GPR[GPR_idx+1], MVT::i32, argHi); + } else { + int FI = MFI->CreateFixedObject(4, ArgOffset+4); + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN); + } // Build the outgoing arg thingy argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi); newroot = argLo; From natebegeman at mac.com Sun Apr 10 01:06:21 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sun, 10 Apr 2005 01:06:21 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200504100606.BAA20022@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.61 -> 1.62 --- Log message: Fix another fixme: factor out the constant fp generation code. --- Diffs of the changes: (+2 -17) PPC32ISelPattern.cpp | 19 ++----------------- 1 files changed, 2 insertions(+), 17 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.61 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.62 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.61 Sun Apr 10 00:53:14 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sun Apr 10 01:06:10 2005 @@ -1305,21 +1305,12 @@ Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register Tmp2 = MakeReg(MVT::f64); // temp reg to load the integer value into Tmp3 = MakeReg(MVT::i32); // temp reg to hold the conversion constant - unsigned ConstF = MakeReg(MVT::f64); // temp reg to hold the fp constant int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); MachineConstantPool *CP = BB->getParent()->getConstantPool(); - // FIXME: pull this FP constant generation stuff out into something like - // the simple ISel's getReg. if (IsUnsigned) { - ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, 0x1.000000p52); - unsigned CPI = CP->getConstantPoolIndex(CFP); - // Load constant fp value - unsigned Tmp4 = MakeReg(MVT::i32); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp4).addReg(getGlobalBaseReg()) - .addConstantPoolIndex(CPI); - BuildMI(BB, PPC::LFD, 2, ConstF).addConstantPoolIndex(CPI).addReg(Tmp4); + unsigned ConstF = getConstDouble(0x1.000000p52); // Store the hi & low halves of the fp value, currently in int regs BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330); addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx); @@ -1328,14 +1319,8 @@ // Generate the return value with a subtract BuildMI(BB, PPC::FSUB, 2, Result).addReg(Tmp2).addReg(ConstF); } else { - ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, 0x1.000008p52); - unsigned CPI = CP->getConstantPoolIndex(CFP); - // Load constant fp value - unsigned Tmp4 = MakeReg(MVT::i32); + unsigned ConstF = getConstDouble(0x1.000008p52); unsigned TmpL = MakeReg(MVT::i32); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp4).addReg(getGlobalBaseReg()) - .addConstantPoolIndex(CPI); - BuildMI(BB, PPC::LFD, 2, ConstF).addConstantPoolIndex(CPI).addReg(Tmp4); // Store the hi & low halves of the fp value, currently in int regs BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330); addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx); From duraid at octopus.com.au Sun Apr 10 04:19:07 2005 From: duraid at octopus.com.au (Duraid Madina) Date: Sun, 10 Apr 2005 04:19:07 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h MachineInstrBuilder.h Message-ID: <200504100919.EAA18172@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.158 -> 1.159 MachineInstrBuilder.h updated: 1.25 -> 1.26 --- Log message: * store immediate values as int64_t, not int. come on, we should be happy when there are immediates, let's not worry about the memory overhead of this :) * add addU64Imm(uint64_t val) to machineinstrbuilder (seriously: this seems required to support 64-bit immediates cleanly. if it _really_ gets on your nerves, feel free to pull it out ;) ) coming up next week: "all your floating point constants are belong to us" --- Diffs of the changes: (+22 -3) MachineInstr.h | 18 +++++++++++++++--- MachineInstrBuilder.h | 7 +++++++ 2 files changed, 22 insertions(+), 3 deletions(-) Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.158 llvm/include/llvm/CodeGen/MachineInstr.h:1.159 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.158 Fri Nov 19 14:46:15 2004 +++ llvm/include/llvm/CodeGen/MachineInstr.h Sun Apr 10 04:18:55 2005 @@ -17,6 +17,7 @@ #define LLVM_CODEGEN_MACHINEINSTR_H #include "llvm/ADT/iterator" +#include "llvm/Support/DataTypes.h" #include #include @@ -117,7 +118,7 @@ // the generated machine code. // LLVM global for MO_GlobalAddress. - int immedVal; // Constant value for an explicit constant + int64_t immedVal; // Constant value for an explicit constant MachineBasicBlock *MBB; // For MO_MachineBasicBlock type const char *SymbolName; // For MO_ExternalSymbol type @@ -138,7 +139,8 @@ memset (&extra, 0, sizeof (extra)); } - MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister) + MachineOperand(int64_t ImmVal = 0, + MachineOperandType OpTy = MO_VirtualRegister) : flags(0), opType(OpTy) { zeroContents (); contents.immedVal = ImmVal; @@ -259,7 +261,7 @@ assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor"); return extra.regNum; } - int getImmedValue() const { + int64_t getImmedValue() const { assert(isImmediate() && "Wrong MachineOperand accessor"); return contents.immedVal; } @@ -605,6 +607,16 @@ MachineOperand(intValue, MachineOperand::MO_UnextendedImmed)); } + /// addZeroExtImm64Operand - Add a zero extended 64-bit constant argument + /// to the machine instruction. + /// + void addZeroExtImm64Operand(uint64_t intValue) { + assert(!OperandsComplete() && + "Trying to add an operand to a machine instr that is already done!"); + operands.push_back( + MachineOperand(intValue, MachineOperand::MO_UnextendedImmed)); + } + /// addSignExtImmOperand - Add a zero extended constant argument to the /// machine instruction. /// Index: llvm/include/llvm/CodeGen/MachineInstrBuilder.h diff -u llvm/include/llvm/CodeGen/MachineInstrBuilder.h:1.25 llvm/include/llvm/CodeGen/MachineInstrBuilder.h:1.26 --- llvm/include/llvm/CodeGen/MachineInstrBuilder.h:1.25 Fri Nov 19 14:46:15 2004 +++ llvm/include/llvm/CodeGen/MachineInstrBuilder.h Sun Apr 10 04:18:55 2005 @@ -108,6 +108,13 @@ return *this; } + /// addU64Imm - Add a new 64-bit immediate operand... + /// + const MachineInstrBuilder &addU64Imm(uint64_t Val) const { + MI->addZeroExtImm64Operand(Val); + return *this; + } + const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB) const { MI->addMachineBasicBlockOperand(MBB); return *this; From lattner at cs.uiuc.edu Sun Apr 10 12:40:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Apr 2005 12:40:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200504101740.j3AHepqj020362@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.78 -> 1.79 --- Log message: don't zextload fp values! --- Diffs of the changes: (+4 -1) LegalizeDAG.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.78 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.79 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.78 Sat Apr 9 23:33:47 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sun Apr 10 12:40:35 2005 @@ -1356,7 +1356,10 @@ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. // FIXME: When the DAG combiner exists, change this to use EXTLOAD! - Result = DAG.getNode(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, VT); + if (MVT::isInteger(NVT)) + Result = DAG.getNode(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, VT); + else + Result = DAG.getNode(ISD::EXTLOAD, NVT, Tmp1, Tmp2, VT); // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); From lattner at cs.uiuc.edu Sun Apr 10 15:45:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Apr 2005 15:45:52 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/fnegsel.ll Message-ID: <200504102045.j3AKjqGn024443@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: fnegsel.ll updated: 1.1 -> 1.2 --- Log message: fix this testcase so the regex doesn't match the function name --- Diffs of the changes: (+1 -1) fnegsel.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/PowerPC/fnegsel.ll diff -u llvm/test/Regression/CodeGen/PowerPC/fnegsel.ll:1.1 llvm/test/Regression/CodeGen/PowerPC/fnegsel.ll:1.2 --- llvm/test/Regression/CodeGen/PowerPC/fnegsel.ll:1.1 Sat Apr 9 04:30:09 2005 +++ llvm/test/Regression/CodeGen/PowerPC/fnegsel.ll Sun Apr 10 15:45:35 2005 @@ -1,6 +1,6 @@ ; RUN: llvm-as < %s | llc -march=ppc32 -enable-ppc-pattern-isel | not grep fneg -double %test_fneg_sel(double %A, double %B, double %C) { +double %test_FNEG_sel(double %A, double %B, double %C) { %D = sub double -0.0, %A %Cond = setgt double %D, -0.0 %E = select bool %Cond, double %B, double %C From lattner at cs.uiuc.edu Sun Apr 10 15:58:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Apr 2005 15:58:35 -0500 Subject: [llvm-commits] CVS: llvm/tools/gccld/GenerateCode.cpp Message-ID: <200504102058.j3AKwZRF024687@apoc.cs.uiuc.edu> Changes in directory llvm/tools/gccld: GenerateCode.cpp updated: 1.44 -> 1.45 --- Log message: The first argument to ExecuteAndWait should be the program name, but pointed out by Markus F.X.J. Oberhumer. --- Diffs of the changes: (+4 -1) GenerateCode.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/tools/gccld/GenerateCode.cpp diff -u llvm/tools/gccld/GenerateCode.cpp:1.44 llvm/tools/gccld/GenerateCode.cpp:1.45 --- llvm/tools/gccld/GenerateCode.cpp:1.44 Mon Feb 28 02:45:35 2005 +++ llvm/tools/gccld/GenerateCode.cpp Sun Apr 10 15:58:21 2005 @@ -300,6 +300,7 @@ const sys::Path &llc) { // Run LLC to convert the bytecode file into assembly code. std::vector args; + args.push_back(llc.c_str()); args.push_back("-f"); args.push_back("-o"); args.push_back(OutputFilename.c_str()); @@ -313,9 +314,10 @@ /// specified bytecode file. int llvm::GenerateCFile(const std::string &OutputFile, const std::string &InputFile, - const sys::Path &llc ) { + const sys::Path &llc) { // Run LLC to convert the bytecode file into C. std::vector args; + args.push_back(llc.c_str()); args.push_back("-march=c"); args.push_back("-f"); args.push_back("-o"); @@ -372,6 +374,7 @@ // and linker because we don't know where to put the _start symbol. // GCC mysteriously knows how to do it. std::vector args; + args.push_back(gcc.c_str()); args.push_back("-fno-strict-aliasing"); args.push_back("-O3"); args.push_back("-o"); From lattner at cs.uiuc.edu Sun Apr 10 15:59:51 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Apr 2005 15:59:51 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-ld/llvm-ld.cpp Message-ID: <200504102059.j3AKxpXL024703@apoc.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ld: llvm-ld.cpp updated: 1.22 -> 1.23 --- Log message: The first argument to ExecuteAndWait should be the program name, but pointed out by Markus F.X.J. Oberhumer. --- Diffs of the changes: (+12 -9) llvm-ld.cpp | 21 ++++++++++++--------- 1 files changed, 12 insertions(+), 9 deletions(-) Index: llvm/tools/llvm-ld/llvm-ld.cpp diff -u llvm/tools/llvm-ld/llvm-ld.cpp:1.22 llvm/tools/llvm-ld/llvm-ld.cpp:1.23 --- llvm/tools/llvm-ld/llvm-ld.cpp:1.22 Sun Feb 13 17:10:45 2005 +++ llvm/tools/llvm-ld/llvm-ld.cpp Sun Apr 10 15:59:38 2005 @@ -221,10 +221,11 @@ const sys::Path &llc) { // Run LLC to convert the bytecode file into assembly code. std::vector args; - args.push_back( "-f"); - args.push_back( "-o"); - args.push_back( OutputFilename.c_str() ); - args.push_back( InputFilename.c_str() ); + args.push_back(llc.c_str()); + args.push_back("-f"); + args.push_back("-o"); + args.push_back(OutputFilename.c_str()); + args.push_back(InputFilename.c_str()); args.push_back(0); return sys::Program::ExecuteAndWait(llc,&args[0]); @@ -237,11 +238,12 @@ const sys::Path &llc) { // Run LLC to convert the bytecode file into C. std::vector args; - args.push_back( "-march=c"); - args.push_back( "-f"); - args.push_back( "-o"); - args.push_back( OutputFile.c_str() ); - args.push_back( InputFile.c_str() ); + args.push_back(llc.c_str()); + args.push_back("-march=c"); + args.push_back("-f"); + args.push_back("-o"); + args.push_back(OutputFile.c_str()); + args.push_back(InputFile.c_str()); args.push_back(0); return sys::Program::ExecuteAndWait(llc, &args[0]); } @@ -290,6 +292,7 @@ // and linker because we don't know where to put the _start symbol. // GCC mysteriously knows how to do it. std::vector args; + args.push_back(gcc.c_str()); args.push_back("-fno-strict-aliasing"); args.push_back("-O3"); args.push_back("-o"); From lattner at cs.uiuc.edu Sun Apr 10 17:54:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Apr 2005 17:54:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200504102254.j3AMsfsF027766@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.79 -> 1.80 --- Log message: Teach legalize to deal with targets that don't support some SEXTLOAD/ZEXTLOADs --- Diffs of the changes: (+38 -13) LegalizeDAG.cpp | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 38 insertions(+), 13 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.79 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.80 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.79 Sun Apr 10 12:40:35 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sun Apr 10 17:54:25 2005 @@ -442,22 +442,47 @@ case ISD::EXTLOAD: case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: + case ISD::ZEXTLOAD: { Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. - if (Tmp1 != Node->getOperand(0) || - Tmp2 != Node->getOperand(1)) - Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1, Tmp2, - cast(Node)->getExtraValueType()); - else - Result = SDOperand(Node, 0); - - // Since loads produce two values, make sure to remember that we legalized - // both of them. - AddLegalizedOperand(SDOperand(Node, 0), Result); - AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); - return Result.getValue(Op.ResNo); + MVT::ValueType SrcVT = cast(Node)->getExtraValueType(); + switch (TLI.getOperationAction(Node->getOpcode(), SrcVT)) { + case TargetLowering::Promote: + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1)) + Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), + Tmp1, Tmp2, SrcVT); + else + Result = SDOperand(Node, 0); + + // Since loads produce two values, make sure to remember that we legalized + // both of them. + AddLegalizedOperand(SDOperand(Node, 0), Result); + AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); + return Result.getValue(Op.ResNo); + break; + case TargetLowering::Expand: + assert(Node->getOpcode() != ISD::EXTLOAD && + "EXTLOAD should always be supported!"); + // Turn the unsupported load into an EXTLOAD followed by an explicit + // zero/sign extend inreg. + Result = DAG.getNode(ISD::EXTLOAD, Node->getValueType(0), + Tmp1, Tmp2, SrcVT); + unsigned ExtOp = Node->getOpcode() == ISD::SEXTLOAD ? + ISD::SIGN_EXTEND_INREG : ISD::ZERO_EXTEND_INREG; + SDOperand ValRes = DAG.getNode(ExtOp, Result.getValueType(), + Result, SrcVT); + AddLegalizedOperand(SDOperand(Node, 0), ValRes); + AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); + if (Op.ResNo) + return Result.getValue(1); + return ValRes; + } + assert(0 && "Unreachable"); + } case ISD::EXTRACT_ELEMENT: // Get both the low and high parts. ExpandOp(Node->getOperand(0), Tmp1, Tmp2); From lattner at cs.uiuc.edu Sun Apr 10 18:37:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 10 Apr 2005 18:37:32 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200504102337.j3ANbWUL028149@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.70 -> 1.71 --- Log message: Don't bother sign/zext_inreg'ing the result of an and operation if we know the result does change as a result of the extend. This improves codegen for Alpha on this testcase: int %a(ushort* %i) { %tmp.1 = load ushort* %i %tmp.2 = cast ushort %tmp.1 to int %tmp.4 = and int %tmp.2, 1 ret int %tmp.4 } Generating: a: ldgp $29, 0($27) ldwu $0,0($16) and $0,1,$0 ret $31,($26),1 instead of: a: ldgp $29, 0($27) ldwu $0,0($16) and $0,1,$0 addl $0,0,$0 ret $31,($26),1 btw, alpha really should switch to livein/outs for args :) --- Diffs of the changes: (+19 -0) SelectionDAG.cpp | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.70 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.71 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.70 Sat Apr 9 23:33:08 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sun Apr 10 18:37:16 2005 @@ -1119,6 +1119,25 @@ if (Opcode == ISD::SIGN_EXTEND_INREG) return N1; break; } + + // If we are sign extending the result of an (and X, C) operation, and we + // know the extended bits are zeros already, don't do the extend. + if (N1.getOpcode() == ISD::AND) + if (ConstantSDNode *N1C = dyn_cast(N1.getOperand(1))) { + uint64_t Mask = N1C->getValue(); + unsigned NumBits = MVT::getSizeInBits(EVT); + if (Opcode == ISD::ZERO_EXTEND_INREG) { + if ((Mask & (~0ULL << NumBits)) == 0) + return N1; + else + return getNode(ISD::AND, VT, N1.getOperand(0), + getConstant(Mask & (~0ULL >> (64-NumBits)), VT)); + } else { + assert(Opcode == ISD::SIGN_EXTEND_INREG); + if ((Mask & (~0ULL << (NumBits-1))) == 0) + return N1; + } + } break; } From natebegeman at mac.com Sun Apr 10 22:02:02 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sun, 10 Apr 2005 22:02:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200504110302.WAA26430@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.80 -> 1.81 --- Log message: Fix libcall code to not pass a NULL Chain to LowerCallTo Fix libcall code to not crash or assert looking for an ADJCALLSTACKUP node when it is known that there is no ADJCALLSTACKDOWN to match. Expand i64 multiply when ISD::MULHU is legal for the target. --- Diffs of the changes: (+30 -5) LegalizeDAG.cpp | 35 ++++++++++++++++++++++++++++++----- 1 files changed, 30 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.80 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.81 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.80 Sun Apr 10 17:54:25 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sun Apr 10 22:01:51 2005 @@ -910,6 +910,8 @@ case ISD::ADD: case ISD::SUB: case ISD::MUL: + case ISD::MULHS: + case ISD::MULHU: case ISD::UDIV: case ISD::SDIV: case ISD::AND: @@ -1678,12 +1680,20 @@ static SDOperand FindInputOutputChains(SDNode *OpNode, SDNode *&OutChain, SDOperand Entry) { SDNode *LatestAdjCallStackDown = Entry.Val; + SDNode *LatestAdjCallStackUp = 0; FindLatestAdjCallStackDown(OpNode, LatestAdjCallStackDown); //std::cerr << "Found node: "; LatestAdjCallStackDown->dump(); std::cerr <<"\n"; - - SDNode *LatestAdjCallStackUp = FindAdjCallStackUp(LatestAdjCallStackDown); - - + + // It is possible that no ISD::ADJCALLSTACKDOWN was found because there is no + // previous call in the function. LatestCallStackDown may in that case be + // the entry node itself. Do not attempt to find a matching ADJCALLSTACKUP + // unless LatestCallStackDown is an ADJCALLSTACKDOWN. + if (LatestAdjCallStackDown->getOpcode() == ISD::ADJCALLSTACKDOWN) + LatestAdjCallStackUp = FindAdjCallStackUp(LatestAdjCallStackDown); + else + LatestAdjCallStackUp = Entry.Val; + assert(LatestAdjCallStackUp && "NULL return from FindAdjCallStackUp"); + SDNode *EarliestAdjCallStackUp = 0; FindEarliestAdjCallStackUp(OpNode, EarliestAdjCallStackUp); @@ -2042,7 +2052,22 @@ ExpandByParts(ISD::SUB_PARTS, Node->getOperand(0), Node->getOperand(1), Lo, Hi); break; - case ISD::MUL: Lo = ExpandLibCall("__muldi3" , Node, Hi); break; + case ISD::MUL: { + if (TLI.getOperationAction(ISD::MULHU, NVT) == TargetLowering::Legal) { + SDOperand LL, LH, RL, RH; + ExpandOp(Node->getOperand(0), LL, LH); + ExpandOp(Node->getOperand(1), RL, RH); + Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); + RH = DAG.getNode(ISD::MUL, NVT, LL, RH); + LH = DAG.getNode(ISD::MUL, NVT, LH, RL); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); + } else { + Lo = ExpandLibCall("__muldi3" , Node, Hi); break; + } + break; + } case ISD::SDIV: Lo = ExpandLibCall("__divdi3" , Node, Hi); break; case ISD::UDIV: Lo = ExpandLibCall("__udivdi3", Node, Hi); break; case ISD::SREM: Lo = ExpandLibCall("__moddi3" , Node, Hi); break; From jeffc at jolt-lang.org Sun Apr 10 22:38:39 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sun, 10 Apr 2005 22:38:39 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h Message-ID: <200504110338.WAA26556@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.159 -> 1.160 --- Log message: Eliminate major source of VC++ "possible loss of data" warnings. --- Diffs of the changes: (+2 -2) MachineInstr.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.159 llvm/include/llvm/CodeGen/MachineInstr.h:1.160 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.159 Sun Apr 10 04:18:55 2005 +++ llvm/include/llvm/CodeGen/MachineInstr.h Sun Apr 10 22:38:28 2005 @@ -275,11 +275,11 @@ } int getFrameIndex() const { assert(isFrameIndex() && "Wrong MachineOperand accessor"); - return contents.immedVal; + return (int)contents.immedVal; } unsigned getConstantPoolIndex() const { assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); - return contents.immedVal; + return (unsigned)contents.immedVal; } GlobalValue *getGlobal() const { assert(isGlobalAddress() && "Wrong MachineOperand accessor"); From jeffc at jolt-lang.org Sun Apr 10 22:44:33 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sun, 10 Apr 2005 22:44:33 -0500 Subject: [llvm-commits] CVS: llvm/lib/System/Win32/DynamicLibrary.inc Program.inc Message-ID: <200504110344.WAA26591@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Win32: DynamicLibrary.inc updated: 1.10 -> 1.11 Program.inc updated: 1.12 -> 1.13 --- Log message: Eliminate tabs --- Diffs of the changes: (+5 -5) DynamicLibrary.inc | 8 ++++---- Program.inc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/lib/System/Win32/DynamicLibrary.inc diff -u llvm/lib/System/Win32/DynamicLibrary.inc:1.10 llvm/lib/System/Win32/DynamicLibrary.inc:1.11 --- llvm/lib/System/Win32/DynamicLibrary.inc:1.10 Fri Feb 18 21:01:13 2005 +++ llvm/lib/System/Win32/DynamicLibrary.inc Sun Apr 10 22:44:22 2005 @@ -92,12 +92,12 @@ if (filename) { HMODULE a_handle = LoadLibrary(filename); - if (a_handle == 0) - ThrowError(std::string(filename) + ": Can't open : "); + if (a_handle == 0) + ThrowError(std::string(filename) + ": Can't open : "); - OpenedHandles.push_back(a_handle); + OpenedHandles.push_back(a_handle); } else { - // When no file is specified, enumerate all DLLs and EXEs in the + // When no file is specified, enumerate all DLLs and EXEs in the // process. EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); } Index: llvm/lib/System/Win32/Program.inc diff -u llvm/lib/System/Win32/Program.inc:1.12 llvm/lib/System/Win32/Program.inc:1.13 --- llvm/lib/System/Win32/Program.inc:1.12 Sat Feb 19 20:48:51 2005 +++ llvm/lib/System/Win32/Program.inc Sun Apr 10 22:44:22 2005 @@ -122,7 +122,7 @@ for (unsigned i = 0; args[i]; i++) { const char *arg = args[i]; - size_t len = strlen(arg); + size_t len = strlen(arg); bool needsQuoting = strchr(arg, ' ') != 0; if (needsQuoting) *p++ = '"';